如何在Entity Framework中创建多对多映射?

时间:2013-10-13 07:37:56

标签: c# entity-framework many-to-many

以下是这种情况,我有2个实体,例如Contract,Media。

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。这些无法添加到媒体实体中。

如何在这种情况下映射?

2 个答案:

答案 0 :(得分:83)

如果要与关联表中的其他数据创建多对多关系,则必须将关联表作为实体。纯粹的多对多关系仅在具有实体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

答案 1 :(得分:7)

无需使用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; }
}