如何在实体框架中创建多对多映射?
Posted
技术标签:
【中文标题】如何在实体框架中创建多对多映射?【英文标题】:How to create a many-to-many mapping in Entity Framework? 【发布时间】:2013-10-20 23:53:59 【问题描述】:这里是这样,我有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 有很多 Media,看起来是多对多的。
但是!!首先在 ef 代码中,我需要 ContractMedia 表中的另外 3 个字段(ef 自动生成)。 例如开始日期、结束日期和价格。这些无法添加到媒体实体中。
在这种情况下如何映射??
【问题讨论】:
Create code first, many to many, with additional fields in association table的可能重复 【参考方案1】:如果要与关联表中的附加数据创建多对多关系,则必须将关联表设为实体。纯多对多关系仅在具有实体 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 APIEntity Framework CodeFirst many to many relationship with additional informationCreate code first, many to many, with additional fields in association table
【讨论】:
我认为ContractMedia
不应该有反向导航集合:Medias
& Contracts
。这些应该是前向导航属性。在我将反向(集合)属性更改为正向属性之前,我在多对多查找表中获得了额外的字段。
@IAbstract 我认为您可能是对的,因为我没有从导航到公用表中检索值。我确信这是由于导航集合
@IAbstract:如何将“反向(集合)属性更改为正向属性。”?
属性有可能吗?
@IAbstract 为了没有双字段,您必须在每一端链接两个导航属性。您可以通过使用 inverseproperty 属性来实现这一点。对于此示例,您可以添加 [InverseProperty("Medias ")] public virtual ICollection无需使用 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;
EF Core 需要使用 Fluent API,但它看起来像这样:
internal class MyContext : DbContext
public MyContext(DbContextOptions<MyContext> options)
: base(options)
public DbSet<Post> Posts get; set;
public DbSet<Tag> Tags get; set;
protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity<Post>()
.HasMany(p => p.Tags)
.WithMany(p => p.Posts)
.UsingEntity<PostTag>(
j => j
.HasOne(pt => pt.Tag)
.WithMany(t => t.PostTags)
.HasForeignKey(pt => pt.TagId),
j => j
.HasOne(pt => pt.Post)
.WithMany(p => p.PostTags)
.HasForeignKey(pt => pt.PostId),
j =>
j.Property(pt => pt.PublicationDate).HasDefaultValueSql("CURRENT_TIMESTAMP");
j.HasKey(t => new t.PostId, t.TagId );
);
public class Post
public int PostId get; set;
public string Title get; set;
public string Content get; set;
public ICollection<Tag> Tags get; set;
public List<PostTag> PostTags get; set;
public class Tag
public string TagId get; set;
public ICollection<Post> Posts get; set;
public List<PostTag> PostTags get; set;
public class PostTag
public DateTime PublicationDate get; set;
public int PostId get; set;
public Post Post get; set;
public string TagId get; set;
public Tag Tag get; set;
来源:
https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key#join-entity-type-configuration
【讨论】:
以上是关于如何在实体框架中创建多对多映射?的主要内容,如果未能解决你的问题,请参考以下文章
如何创建如何在 typeorm 中创建多对多关系,[NestJS]