删除 Entity Framework 中嵌套集合的元素

Delete elements of nested collections in Entity Framework

我正在使用 Entity Framework 来存储以下实体的对象 类:

public class Library
{
    public int Id { get; set; }

    private ICollection<Book> _books;
    public virtual ICollection<Book> Books => _books ?? (_books = new List<Book>());
}

public class Book
{
    public int Id { get; set; }

    public int LibraryId { get; set; }
    public virtual Library Library { get; set; }

    private ICollection<Page> _pages;
    public virtual ICollection<Page> Pages => _pages ?? (_pages = new List<Page>());
}

public class Page
{
    public int Id { get; set; }

    public int BookId { get; set; }
    public virtual Book Book { get; set; }
}

我希望能够从相应的集合中删除单独的页面和书籍,所以我用流利的API进行了以下配置:

modelBuilder.Entity<Library>()
    .HasMany(library => library.Books)
    .WithOptional()
    .HasForeignKey(book => book.LibraryId);
modelBuilder.Entity<Book>()
    .HasKey(book => new { book.Id, book.LibraryId })
    .Property(book => book.Id)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

modelBuilder.Entity<Book>()
    .HasMany(book => book.Pages)
    .WithOptional()
    .HasForeignKey(page => page.BookId);
modelBuilder.Entity<Page>()
    .HasKey(page => new { page.Id, page.BookId })
    .Property(page => page.Id)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

我为 BookPage 创建复合键并设置一对多关系。

当我尝试创建迁移时出现以下错误:

Book_Pages_Source_Book_Pages_Target: : The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical.

我怀疑错误出在 Page 的外键上,它可能应该包括 LibraryId,因为它是 Book 的 PK 的一部分...我应该怎么办修复配置?

正如 orhtej2 在上面的评论中指出的,Page 的 FK 关系错过了 LibraryId,因为这个值也是 Book 的 PK 的一部分。我已经放弃了流利的 API 并改用数据注释。以下实体 类 正在做我需要的事情:

public class Library
{
    [Key]
    public int Id { get; set; }

    private ICollection<Book> _books;
    public virtual ICollection<Book> Books => _books ?? (_books = new List<Book>());
}       

public class Book
{   
    [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Key, Column(Order = 1), ForeignKey("Library")]
    public int LibraryId { get; set; }
    public virtual Library Library { get; set; }

    private ICollection<Page> _pages;
    public virtual ICollection<Page> Pages => _pages ?? (_pages = new List<Page>());
}

public class Page
{
    [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Key, Column(Order = 1), ForeignKey("Book")]
    public int BookId { get; set; }
    [Key, Column(Order = 2), ForeignKey("Book")]
    public int LibraryId { get; set; }
    public virtual Book Book { get; set; }
}

需要 BookPage 中的复合键来确保当我从一本书的 Pages 集合中删除一个项目时,不仅是PageBook 之间的关系已删除,而且存储页面的记录实际上已从数据库中删除(如 this answer 中所述)。