我使用的是.NET Core 1.1.0,EF Core 1.1.0,VS 2015。
我正在为帖子/评论编写一个系统,我需要一个函数来加载评论及其所有子项及其相关属性。这是我的课程的简化版本:
public class Comment
{
public long Id { get; set; }
public string Content { get; set; }
public User User { get; set; }
public ICollection<Comment> Replies { get; set; }
}
public class User
{
public long Id { get; set; }
public string Name { get; set; }
public Avatar Avatar { get; set; }
}
public class Avatar
{
public string Url { get; set; }
}
任何给定的评论都可以有任意数量的回复:
-PARENT
-CHILD 1
-CHILD 2
-CHILD 3
-CHILD 4
-CHILD 5
-CHILD 6
-CHILD 7
因此,给定父评论的ID,我需要加载整个树,包括用户及其各自的头像。 (我在其他地方有控制以确保这些树不会变得笨重,我不担心这一点可能会抓住太多数据。)
EF Core文档中的Loading Related Data页面非常有用,但我不确定如何最好地处理这个问题。我已经尝试将一些东西放在一起,但我无法概念化如何将它们整合在一起。再次注意:我正在使用EF Core 1.1.0,因此我可以访问“显式加载”部分中的函数。
如何根据父评论的ID加载整个评论树?
答案 0 :(得分:3)
我没有数据库,所以我只是在内存中做了,但是如果你按照我的意见,它将适合你。注意我在内存中的对象,只有id为2的注释有回复。
SQL>EXEC DBMS_SCHEDULER.STOP_JOB (job_name => 'JOB_NAME');
方法是一切都发生的地方。其余的只是我需要的设置代码。
LoadComment
答案 1 :(得分:1)
为什么不使用Eagerly Loading? 急切地加载多个级别 我在.NETCore(VS2015)的项目中使用过它
也可能急切地加载多个级别的相关实体。下面的查询显示了如何对集合和引用导航属性执行此操作的示例。
using (var context = new BloggingContext())
{
// Load all blogs, all related posts, and all related comments
var blogs1 = context.Blogs
.Include(b => b.Posts.Select(p => p.Comments))
.ToList();
// Load all users their related profiles, and related avatar
var users1 = context.Users
.Include(u => u.Profile.Avatar)
.ToList();
// Load all blogs, all related posts, and all related comments
// using a string to specify the relationships
var blogs2 = context.Blogs
.Include("Posts.Comments")
.ToList();
// Load all users their related profiles, and related avatar
// using a string to specify the relationships
var users2 = context.Users
.Include("Profile.Avatar")
.ToList();
}
请注意,目前无法过滤加载了哪些相关实体。包含将始终引入所有相关实体。
这是我的参考:"Microsoft.EntityFrameworkCore.SqlServer": "1.1.0-preview2-22683"
我希望它可以帮到你。
答案 2 :(得分:0)
这就是我解决的方法。与Yoshi的相似,但对某人可能会有帮助。
private async Task<Comment> GetComment(Guid id, CancellationToken cancellationToken)
{
var wm = await _context.Comments
.Include(x => x.Replies)
.SingleOrDefaultAsync(x => x.Id == id, cancellationToken);
for (var i = 0; i < wm.Replies.Count; i++)
{
if (!wm.Replies[i].IsDeleted)
wm.Replies[i] = await GetComment(wm.Replies[i].Id, cancellationToken);
}
return wm;
}