【问题标题】:Using Fluent API instead of InverseProperty and navigational properties使用 Fluent API 而不是 InverseProperty 和导航属性
【发布时间】:2013-08-07 17:49:54
【问题描述】:

我有一个数据库模型,其中模型之间存在关系,这给 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 包含同一本书,并且 db.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 完成?

我之前发布了一个类似的问题,但由于问题与问题无关,所以删除了它

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    使用WithMany()在Book实体中配置多对多关系,无需导航属性:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-15
      相关资源
      最近更新 更多