C# 使用EF Core 5.0加载自引用实体(只需在其导航属性中获取父对象及其子对象)
我想实现一个评论系统这是我的评论实体C# 使用EF Core 5.0加载自引用实体(只需在其导航属性中获取父对象及其子对象),c#,entity-framework-core,ef-core-3.1,self-reference,ef-core-5.0,C#,Entity Framework Core,Ef Core 3.1,Self Reference,Ef Core 5.0,我想实现一个评论系统这是我的评论实体 public class Comment { public int CommentId { get; set; } public int? ParentId { get; set; } public string Content { get; set; } public DateTimeOffset DateCreated { get; set; } public D
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; }
}
公共类注释
{
public int CommentId{get;set;}
public int?ParentId{get;set;}
公共字符串内容{get;set;}
public DateTimeOffset DateCreated{get;set;}
public DateTimeOffset DateModified{get;set;}
公共注释父项{get;set;}
公共ICollection子项{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);
});
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
实体(注释=>
{
HasKey(c=>c.CommentId);
comment.HasIndex(c=>c.ParentId);
comment.HasOne(c=>c.Parent)
.有许多(c=>c.儿童)
.HasForeignKey(c=>c.ParentId);
});
}
一切正常,我可以用这段代码加载所有具有层次结构的记录(包括父记录和子记录)
List<Comment> comments = await _db.Comments.Include(c => c.Children)
.ToListAsync();
List comments=await\u db.comments.Include(c=>c.Children)
.ToListAsync();
但此代码加载所有元素,例如子元素。但我想让所有的父母,然后是他们的孩子,然后是孙子和
我将此代码用于此场景
List<Comment> comments = await _db.Comments.Include(c => c.Children)
.Where(c => c.ParentId == null)
.ToListAsync();
List comments=await\u db.comments.Include(c=>c.Children)
.Where(c=>c.ParentId==null)
.ToListAsync();
这段代码只是把所有的父母和他们的孩子一起加载,而不是大孩子和其他层次结构中的孩子
如何编写此查询?我找到了此场景的解决方案
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);
}
公共异步任务索引()
{
列表注释=等待_db.comments.AsNoTrackingWithIdentityResolution()
.包括(c=>c.儿童)
.ToListAsync();
//将注释结构化到树中
列表commentsTree=comments.Where(c=>c.ParentId==null)
.天冬酰胺()
.ToList();
返回视图(commentsTree);
}
这是一个非常复杂的查询,我建议将其写入服务器上的存储过程或表值函数中,然后从EF查询。EF没有游标的概念,我相信你会发现你需要它们。或者至少是非常精确的CTE查询。请查找有关LINQ+层次结构或递归的其他问题。这是一个不断重复的话题。