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

Kra*_*tos 48 c# many-to-many entity-framework

在这种情况下,我有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..*
}
Run Code Online (Sandbox Code Playgroud)

合同有很多媒体,似乎它们是多对多的.

但!!首先,在ef代码中,我需要在ContractMedia表中增加3个字段(如果自动生成).例如StartDate,EndDate和Price.这些无法在媒体实体中添加.

如何在这种情况下映射?

Tom*_*mas 90

如果要与关联表中的其他数据创建多对多关系,则必须将关联表作为实体.纯粹的多对多关系仅在具有实体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; }
}
Run Code Online (Sandbox Code Playgroud)

在创建模型/实体后,您需要在上下文中定义关系:

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);  
}
Run Code Online (Sandbox Code Playgroud)

您还可以参考以下链接:
Fluent API
实体框架中的多个字段与多余字段的多对多映射CodeFirst与其他信息的多对多关系通过
关联表中的其他字段创建代码优先,多对多

  • 我认为`ContractMedia`不应该有反向导航集合:`Medias`和`Contracts`.这些应该是前向导航属性.我在多次查找表中获取了额外的字段,直到我将reverse(集合)属性更改为转发属性. (6认同)

Ogg*_*las 13

无需使用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; }
}
Run Code Online (Sandbox Code Playgroud)