【问题标题】:How can I directly fill join table generated by EF Core for many-to-many relationship?如何直接填充由 EF Core 生成的多对多关系连接表?
【发布时间】: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 字段。

【问题讨论】:

    标签: c# entity-framework-core many-to-many ef-core-5.0


    【解决方案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 版本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-25
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 2016-06-13
      • 2016-01-09
      相关资源
      最近更新 更多