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

时间:2020-12-30 16:42:05

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

我有这些实体:

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 填充连接表,而不是先从上下文中获取这些实体,然后将流派实体添加到 Book 实体的流派字段。

1 个答案:

答案 0 :(得分:0)

如果查看 docsother docs,可以看到可以访问导航,但是文档中指出这可能会在以后更改。 Do not depend on the join type being Dictionary<string, object> 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 版本。