我在Members和Books之间创建了一种多对多的关系。我的目标是能够显示给定Member读过的所有书籍,以及所有读过给定Book的成员。
每个Member都有一个List<BookMember> BooksRead,每个Book都有一个List<BookMember> MembersWhoHaveRead。这可以很好地工作,并且在数据库中为这些关系创建了一个正确的连接表。
当用户添加已阅读的图书时,我的UI成功地将BookMember添加到连接表中,但Member中的List<BookMember>无法识别此添加,因此以下代码继续显示消息:“您尚未阅读任何图书。在下面添加一本!”,并且刚刚添加的图书仍在下拉菜单中:
<div class="card">
<div class="card-header">
<b>Books</b>
</div>
@if (Model.UserProfileUpdateModel.BooksRead.Count > 0)
{
@foreach (var book in Model.Books)
{
if (Model.UserProfileUpdateModel.HasReadBook(book))
{
<div class="card-body">
@book.ToString()
</div>
}
}
}
else
{
<div class="card-body">You haven't read any books yet. Add one below!</div>
}
<div class="card-body">
<label for="addBooks">Select a book below to add it to your list.</label>
<select asp-for="UserProfileUpdateModel.AddedBook" id="addBooks">
<option value="">None</option>
@foreach (var book in Model.Books)
{
if (!(Model.UserProfileUpdateModel.HasReadBook(book)))
{
<option value="@book.Id">@book.ToString()</option>
}
}
</select>
</div>
</div>这段代码应该显示Member (从UserProfileUpdateModel引用)已经阅读的所有书籍,以及消息“您还没有读过任何书籍。在下面添加一本!”如果没有书的话。它还应该显示一个下拉菜单,列出此Member尚未阅读的所有可用书籍。
我检查了HasReadBook方法是否按预期工作;它只查看Member的BooksRead列表,如果图书在该列表中,则返回true。
有趣的是,当BookMember第一次添加到数据库中时,下拉菜单会根据需要进行更新,以便不显示刚刚添加的图书。但是,如果页面重新加载或应用程序重新运行,则下拉菜单将显示该书。
从本质上讲,我需要知道为什么我的多对多关系不更新Book和Member中的列表,即使它正在更新数据库。下面是来自Member、Book和BookMember的相关代码
public class Member : BaseEntity
{
...
public List<BookMember> BooksRead { get; } = new List<BookMember>();
...
}
public class Book : BaseEntity
{
...
public List<BookMember> MembersWhoHaveRead { get; } = new List<BookMember>();
...
}
public class BookMember
{
public int BookId { get; set; }
public Book Book { get; set; } = new Book();
public int MemberId { get; set; }
public Member Member { get; set; } = new Member(string.Empty);
}出于完成的目的,下面也是HasReadBook方法:
public bool HasReadBook(Book book)
{
if (BooksRead == null)
{
return false;
}
foreach (BookMember bookMember in BooksRead)
{
if (bookMember != null && bookMember.Book != null && bookMember.Book.Equals(book))
{
return true;
}
}
return false;
}编辑:这是BookMemberConfig
public class BookMemberConfig : IEntityTypeConfiguration<BookMember>
{
public void Configure(EntityTypeBuilder<BookMember> builder)
{
builder.HasKey(x => new { x.BookId, x.MemberId });
builder.HasOne(bookmember => bookmember.Book)
.WithMany(b => b.MembersWhoHaveRead)
.HasForeignKey(b => b.BookId);
builder.HasOne(bookmember => bookmember.Member)
.WithMany(m => m.BooksRead)
.HasForeignKey(m => m.MemberId);
}
}发布于 2020-09-23 03:53:55
如果您的表是正确创建和填充的,则可能是您没有在查询中检索相关实体和/或没有正确配置导航属性。
检索相关实体的
确保在相关的读取方法中使用Include和ThenInclude,即:
ICollection<Member> LoadAllMembers()
{
return _dbContext.Members
.Include(member => member.BooksRead)
.ThenInclude(bookMember => bookMember.Book)
.ToList();
}配置导航属性
如果您使用的是早于v5.0.0的EF Core版本,我建议您遵循Arthur Vickers (EF工程经理)关于设置多对多关系和正确配置相关导航属性的系列文章,因为这不是一件容易做的事情。
这些类型的联合实体aren't required anymore from EF Core v5.0.0,其中基本的多对多关系配置得到简化。
https://stackoverflow.com/questions/64016188
复制相似问题