C# 如何在实体框架中创建多对多映射?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19342908/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:47:53  来源:igfitidea点击:

How to create a many-to-many mapping in Entity Framework?

c#entity-frameworkmany-to-many

提问by Kratos

Here is the case, I have 2 entities, such as Contract、Media。

就是这样,我有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..*
}

Contract has many Medias, it seems that they are many to many.

契约有很多媒体,似乎是多对多。

But!! at ef code first, i need 3 more fields in the ContractMedia table(ef auto generated). such as StartDate,EndDate and Price. these could not be added in Media entity.

但!!首先在 ef 代码中,我需要 ContractMedia 表中的另外 3 个字段(ef 自动生成)。例如开始日期、结束日期和价格。这些无法添加到媒体实体中。

How to map at this case??

在这种情况下如何映射?

采纳答案by Tomas

If you want to create many to many relationship with additional data in association table, you have to make the association table as entity. The pure many to many relationship is only in pure table with entity id's.

如果要与关联表中的附加数据创建多对多关系,则必须将关联表作为实体。纯多对多关系仅在具有实体 ID 的纯表中。

In you case it will be:

在你的情况下,它将是:

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

And after you created models/entities, you need to define relationships in context:

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

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

Also you can refer to these links:
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

您也可以参考这些链接:
多对多映射与 Fluent API
实体框架中的额外字段CodeFirst 多对多关系与附加信息 先
创建代码,多对多,在关联表中附加字段

回答by Ogglas

Adding to @Tomas answer without having to use Fluent API.

添加到@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; }
}