在EF Core中实现递归属性加载

时间:2016-12-06 03:32:09

标签: c# entity-framework asp.net-core entity-framework-core

我使用的是.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加载整个评论树?

3 个答案:

答案 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;
}