首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EF核心多对多关系与网络实体不能正常工作

EF核心多对多关系与网络实体不能正常工作
EN

Stack Overflow用户
提问于 2020-09-23 03:04:36
回答 1查看 98关注 0票数 0

我在MembersBooks之间创建了一种多对多的关系。我的目标是能够显示给定Member读过的所有书籍,以及所有读过给定Book的成员。

每个Member都有一个List<BookMember> BooksRead,每个Book都有一个List<BookMember> MembersWhoHaveRead。这可以很好地工作,并且在数据库中为这些关系创建了一个正确的连接表。

当用户添加已阅读的图书时,我的UI成功地将BookMember添加到连接表中,但Member中的List<BookMember>无法识别此添加,因此以下代码继续显示消息:“您尚未阅读任何图书。在下面添加一本!”,并且刚刚添加的图书仍在下拉菜单中:

代码语言:javascript
复制
<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方法是否按预期工作;它只查看MemberBooksRead列表,如果图书在该列表中,则返回true。

有趣的是,当BookMember第一次添加到数据库中时,下拉菜单会根据需要进行更新,以便不显示刚刚添加的图书。但是,如果页面重新加载或应用程序重新运行,则下拉菜单将显示该书。

从本质上讲,我需要知道为什么我的多对多关系不更新BookMember中的列表,即使它正在更新数据库。下面是来自MemberBookBookMember的相关代码

代码语言:javascript
复制
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方法:

代码语言:javascript
复制
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

代码语言:javascript
复制
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);
        }
    }
EN

回答 1

Stack Overflow用户

发布于 2020-09-23 03:53:55

如果您的表是正确创建和填充的,则可能是您没有在查询中检索相关实体和/或没有正确配置导航属性。

检索相关实体的

确保在相关的读取方法中使用IncludeThenInclude,即:

代码语言:javascript
复制
ICollection<Member> LoadAllMembers()
{
    return _dbContext.Members
        .Include(member => member.BooksRead)
        .ThenInclude(bookMember => bookMember.Book)
        .ToList();
}

配置导航属性

如果您使用的是早于v5.0.0的EF Core版本,我建议您遵循Arthur Vickers (EF工程经理)关于设置多对多关系和正确配置相关导航属性的系列文章,因为这不是一件容易做的事情。

Part 1part 2part 3part 4

这些类型的联合实体aren't required anymore from EF Core v5.0.0,其中基本的多对多关系配置得到简化。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64016188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档