使用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实现这一点?
我之前发布了一个类似的问题,但删除了它,因为该问题与问题无关
使用WithMany()
配置Book实体中没有导航属性的多对多关系:
modelBuilder.Entity<BookReader>()
.HasMany(r => r.ReadBooks)
.WithMany();
这将创建以BookReader_ID
和Book_ID
为主键的连接表BookReaderBooks。您还可以为表和键指定自己漂亮的名称:
.WithMany().Map(mc => mc.MapLeftKey("ReaderId").MapRightKey("BookId"));