使用 EF Core 5.0 加载自引用实体(只需在导航 属性 中获取 Parents 及其 children )

Load Self Referencing Entity With EF Core 5.0 ( Just get Parents and their children in their navigation property )

我想实现一个评论系统,这是我的评论实体。

 public class Comment
    {
        public int CommentId { get; set; }
        public int? ParentId  { get; set; }
        public string Content { get; set; }
        public DateTimeOffset DateCreated { get; set; }
        public DateTimeOffset DateModified { get; set; }


        public Comment Parent { get; set; }
        public ICollection<Comment> Children { get; set; }


    }

这是我在 Fluent 中的配置 API


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<Comment>(comment =>
            {
                comment.HasKey(c => c.CommentId);
                comment.HasIndex(c => c.ParentId);

                comment.HasOne(c => c.Parent)
                       .WithMany(c => c.Children)
                       .HasForeignKey(c => c.ParentId);
            });
        }

一切正常,我可以使用此代码加载所有具有层次结构的记录(包括 parent 和 children)

  List<Comment> comments = await _db.Comments.Include(c => c.Children)
                .ToListAsync();

但是此代码加载所有元素,例如 children。但我想加载所有 Parents 然后是他们的孩子,然后是孙子和 .​​...

这个场景我用这个代码

List<Comment> comments = await _db.Comments.Include(c => c.Children)
                .Where(c => c.ParentId == null)
                .ToListAsync();

并且此代码仅加载所有 parent 及其 children 而不是孙辈和更多层次结构。

我该如何编写这个查询?

我找到了这个场景的解决方案。

  public async Task<IActionResult> Index()
        {

            List<Comment> comments = await _db.Comments.AsNoTrackingWithIdentityResolution()
                                                        .Include(c => c.Children)
                                                        .ToListAsync();

            // Structure Comments into a tree
            List<Comment> commentsTree = comments.Where(c => c.ParentId == null)
                                                 .AsParallel()
                                                 .ToList();

            return View(commentsTree);
        }