使用Fluent API而不是InverseProperty和导航属性

本文关键字:InverseProperty 导航 属性 Fluent API 使用 | 更新日期: 2023-09-27 18:26:52

我有一个数据库模型,其中模型之间存在关系,这给Code First带来了一些问题。下面是一个构造示例。

一个读者可以读过几本书,一本书也可以被几个读者读过。此外,每个读者可能都有一本自己喜欢的书。

//not-working model
public class BookReader
{
    public virtual List<Book> ReadBooks { get; set; }
    public virtual Book FavoriteBook { get; set; }
    public int ID { get; set; }
}
public class Book
{
    public string BookName { get; set; }
    public int ID { get; set; }
}

这样做效果不太好。如果在代码中,多个阅读器被设置为读过同一本书,那么只有一个阅读器会将其保存到数据库中(可能是最后一组)。

此外,如果BookReader.FavoriteBook和BookReader.ReadBooks包含相同的图书和数据库。SaveChanges()创建了这个新书(而不是现有的数据库实体),它将导致此错误:
保存不公开其关系的外键属性的实体时出错

这是我对InverseProperty和导航属性的修复。

//working model
public class BookReader
{
    [InverseProperty("CurrentReaders")]
    public virtual List<Book> ReadBooks { get; set; }
    public virtual Book FavoriteBook { get; set; }
    public int ID { get; set; }
}
public class Book
{
    public string BookName { get; set; }
    public int ID { get; set; }
    //new, unwanted, property
    public virtual List<BookReader> CurrentReaders { get; set; }
}


我不想这样改变模式。有没有一种方法可以在不改变模型的情况下使用Fluent API实现这一点?

我之前发布了一个类似的问题,但删除了它,因为该问题与问题无关

使用Fluent API而不是InverseProperty和导航属性

使用WithMany()配置Book实体中没有导航属性的多对多关系:

modelBuilder.Entity<BookReader>()
    .HasMany(r => r.ReadBooks)
    .WithMany();

这将创建以BookReader_IDBook_ID为主键的连接表BookReaderBooks。您还可以为表和键指定自己漂亮的名称:

.WithMany().Map(mc => mc.MapLeftKey("ReaderId").MapRightKey("BookId"));