使用Fluent API代替InverseProperty和导航属性

Jen*_*ens 5 c# entity-framework

我有一个数据库模型,其中模型之间存在关系,这给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; }
}
Run Code Online (Sandbox Code Playgroud)

这不是很好。如果在代码中将多个读者设置为阅读同一本书,则只有一位读者会将其保存到数据库(可能是最后一组)。

另外,如果BookReader.FavoriteBook和BookReader.ReadBooks包含同一本书,并且db.SaveChanges()创建此新书(不是现有的db实体),则会导致此错误:
保存不公开外键的实体时发生错误关系的属性。

这是我对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; }
}
Run Code Online (Sandbox Code Playgroud)


我不希望这样更改模型。有没有一种方法可以使用Fluent API来完成而无需更改模型?

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

Ser*_*kiy 4

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

modelBuilder.Entity<BookReader>()
    .HasMany(r => r.ReadBooks)
    .WithMany();
Run Code Online (Sandbox Code Playgroud)

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

.WithMany().Map(mc => mc.MapLeftKey("ReaderId").MapRightKey("BookId"));
Run Code Online (Sandbox Code Playgroud)