2013-10-13 118 views
36

這裏的話,我有2個實體,如合同,媒體。如何在實體框架中創建多對多的映射?

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

如果要與關聯表中的其他數據創建多對多關係,則必須將關聯表作爲實體。純粹的多對多關係只能在純表中使用實體標識。

在你區分這將是:

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'。這些應該是轉發導航屬性。 直到我將逆(集合)屬性更改爲轉發屬性之前,我在許多查找表中獲取了額外字段。 – IAbstract

+0

@IAbstract我認爲你可以是正確的,因爲我沒有從導航到公共表檢索值。我相信這是由於導航集合 – 2014-05-02 12:21:41

+0

@IAbstract:你如何改變「反轉(集合)屬性轉發屬性。」? – eugenekgn

1

添加到@Tomas的答案,而無需使用Fluent API。

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; } 
}