如何直接填充由 EF Core 生成的多对多关系连接表?

Posted

技术标签:

【中文标题】如何直接填充由 EF Core 生成的多对多关系连接表?【英文标题】:How can I directly fill join table generated by EF Core for many-to-many relationship? 【发布时间】:2021-04-07 03:54:58 【问题描述】:

我有这些实体:

public class Book

  public int Id  get; set; 
  public string Title  get; set; 
  public List<Genre> Genres  get; set; 


public class Genre

  public int Id  get; set; 
  public string Name  get; set; 
  public List<Book> Books  get; set; 

EF Core 5 可以处理创建连接表,但我该如何使用这个表,我应该这样做吗?例如,我正在发送响应以将两个现有类型添加到现有书籍(我有书籍和类型 ID)。我想最好直接用这个 id 填充连接表,而不是先从上下文中获取这些实体,然后将 Genre 实体添加到 Book 实体的 Genres 字段。

【问题讨论】:

【参考方案1】:

如果您查看docs 和other docs,您可以看到您可以访问导航,但在文档中指出这可能会在以后更改。 Do not depend on the join type being Dictionary&lt;string, object&gt; unless this has been explicitly configured.

所以我会手动创建一个JoinTable,真的没那么难:

public class Book

  public int Id  get; set; 
  public string Title  get; set; 
  public List<BookGenre> BookGenres  get; set; 


public class Genre

  public int Id  get; set; 
  public string Name  get; set; 
  public List<BookGenre> BookGenres  get; set; 


public class BookGenre

  public int GenreId  get; set; 
  public int BookId  get; set; 

  public Genre Genre  get; set; 
  public Book Book  get; set; 

如果您觉得有能力,您可以添加Fluent-api 配置,这样您就可以尽可能少地依赖 EF。在您的上下文中的OnModelCreatingMethod 或您单独的Configuration 文件中添加(可选):

builder.Entity<BookGenre>()
  .ToTable("BookGenre")
  .HasKey(_ => new  _.BookId, _.GenreId );

builder.Entity<BookGenre>()
  .Property(_ => _.BookId)
  .ValueGeneratedNever();

builder.Entity<BookGenre>()
  .Property(_ => _.GenreId)
  .ValueGeneratedNever();

builder.Entity<BookGenre>()
  .HasOne(_ => _.Book)
  .WithMany(_ => _.BookGenres)
  .HasForeignKey(_ => _.BookId);

builder.Entity<BookGenre>()
  .HasOne(_ => _.Genre)
  .WithMany(_ => _.BookGenres)
  .HasForeignKey(_ => _.GenreId);

您还需要将 JoinTable 添加到您的上下文中:

public DbSet<BookGenre> BookGenreRelations  get; set; 

现在你可以添加新的关系了:

this.myContext.BookGenreRelations.Add(new BookGenre 
  BookId = myBookId,
  GenreId = myGenreId,
);

this.myContext.SaveChanges();

注意:在上述示例中,您也可以使用async 版本。

【讨论】:

以上是关于如何直接填充由 EF Core 生成的多对多关系连接表?的主要内容,如果未能解决你的问题,请参考以下文章

EF Core中如何设置数据库表自己与自己的多对多关系

EF Core中的多对多映射如何实现?

使用流利的 api EF Core 5 的多对多关系

EF Core 5.0 - 更新 ASP.NET Core Web API 中的多对多实体

如何有效地迭代 NSSet (Objective-C) - Core Data 中的多对多关系表示?

EF Core 5.0 中的多对多关系是不是可以配置为仅保留一个导航属性(在一侧)?