2013-10-13 17 views
36

は、私は、このような契約、メディアとしての2つのエンティティを、持っている、場合である。Entity Frameworkで多対多マッピングを作成する方法は?ここで

public class Media : Entity 
{ 
    public string Name {get; set;} 
    public bool Enabled 
    *//other properties can be ignored..* 
} 

public class Contract : Entity 
{ 
    public string Code {get; set;} 
    *//other properties can be ignored..* 
} 

契約は、多くのメディアシュを持っている、彼らが多くの多くあるようです。

ただし、 efコードでは、ContractMediaテーブルに3つ以上のフィールドが必要です(自動生成されます)。 StartDate、EndDate、Priceなどの これらはMediaエンティティに追加できませんでした。

この場合のマップ方法は?

+0

可能重複http://stackoverflow.com/questions/7050404/create-code-first-many-to-many-([関連テーブルの追加フィールドで、多くに多く、最初のコードの作成] with-additional-fields-in-association-table) – forsvarir

答えて

73

アソシエーションテーブル内の追加データと多対多リレーションシップを作成する場合は、関連テーブルをエンティティとして作成する必要があります。純粋な多対多の関係は、エンティティIDを持つ純粋なテーブルのみです。あなたに

それがされるケース:

public class Media // One entity table 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public bool Enabled { get; set; } 

    public virtual ICollection<ContractMedia> ContractMedias { get; set; } 
} 

public class Contract // Second entity table 
{ 
    public int Id { get; set; } 
    public string Code { get; set } 

    public virtual ICollection<ContractMedia> ContractMedias { get; set; } 
} 

public class ContractMedia // Association table implemented as entity 
{ 
    public int MediaId { get; set; } 
    public int ContractId { get; set; } 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 
    public double Price { get; set; } 

    public virtual Media Media { get; set; } 
    public virtual Contract Contract { get; set; } 
} 

そして、あなたは、モデル/エンティティを作成した後、あなたはコンテキスト内の関係を定義する必要があります。

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<ContractMedia>() 
     .HasKey(c => new { c.MediaId, c.ContractId }); 

    modelBuilder.Entity<Contract>() 
     .HasMany(c => c.ContractMedias) 
     .WithRequired() 
     .HasForeignKey(c => c.ContractId); 

    modelBuilder.Entity<Media>() 
     .HasMany(c => c.ContractMedias) 
     .WithRequired() 
     .HasForeignKey(c => c.MediaId); 
} 

また、あなたがこれらのリンクを参照できます。
Many to many mapping with extra fields in Fluent API
Entity Framework CodeFirst many to many relationship with additional information
Create code first, many to many, with additional fields in association table

+5

'ContractMedia'には' Medias'と 'Contracts'の逆のnavコレクションがあるべきではないと思います。代わりに前方のナビゲーションプロパティが必要です。 inverse(collection)プロパティをforwardプロパティに変更するまで、多くのルックアップテーブルで余分なフィールドを取得していました。 – IAbstract

+0

@IAbstract私は共通テーブルへのナビゲーションから値を取得しないので、正しいかもしれないと思います。そして、それはnavコレクションのためだと確信しています –

+0

@IAbstract:どのようにプロパティを転送するためにinverse(collection)プロパティを変更しますか? – eugenekgn

1

Fluent APIを使用せずに@Tomasに追加すると答えます。

public class Media // One entity table 
{ 
    public int Id { get; set; } 

    public string Name { get; set; } 

    public virtual ICollection<ContractMedia> ContractMedias { get; set; } 
} 

public class Contract // Second entity table 
{ 
    public int Id { get; set; } 

    public string Code { get; set } 

    public virtual ICollection<ContractMedia> ContractMedias { get; set; } 
} 

public class ContractMedia // Association table implemented as entity 
{ 
    [Key] 
    [Column(Order = 0)] 
    [ForeignKey("Media")] 
    public int MediaId { get; set; } 

    [Key] 
    [Column(Order = 1)] 
    [ForeignKey("Contract")] 
    public int ContractId { get; set; } 

    public DateTime StartDate { get; set; } 

    public DateTime EndDate { get; set; } 

    public double Price { get; set; } 

    public virtual Media Media { get; set; } 

    public virtual Contract Contract { get; set; } 
} 
関連する問題