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

vai*_*dil 6 c# entity-framework entity-framework-core asp.net-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; }
}
Run Code Online (Sandbox Code Playgroud)

任何给定的评论都可以有任意数量的回复:

-PARENT
    -CHILD 1
    -CHILD 2
        -CHILD 3
    -CHILD 4
    -CHILD 5
        -CHILD 6
            -CHILD 7
Run Code Online (Sandbox Code Playgroud)

因此,给定父评论的ID,我需要加载整个树,包括用户及其各自的头像.(我在其他地方有控制以确保这些树不会变得笨拙,我不担心这一点可能会抓取过多的数据.)

EF Core文档中的" 加载相关数据"页面非常有用,但我不确定如何最好地处理此问题.我已经尝试将一些东西放在一起,但我无法概念化如何将它们整合在一起.再次注意:我正在使用EF Core 1.1.0,因此我可以访问"显式加载"部分中的函数.

如果给出父评论的ID,我如何加载整个评论树?

Cod*_*shi 3

我没有数据库,所以我只是在内存中完成它,但如果你遵循我的评论,它会对你有用。注意我内存中的对象,只有 id 2 的评论有回复。

LoadComment方法是一切发生的地方。剩下的只是我需要的设置代码。

class Program
{
    static void Main(string[] args)
    {
        var result = LoadComment(1, null);
        Console.ReadKey();

    }



public static Comment LoadComment(long id, Comment com) 
{
   Comment res = new Comment();
   if( com == null ) 
   {
      // You would call your context here and write db.Single(x => x.Id == id).Include(x => x.User.Avatar);
      var first = db.Single( x => x.Id == id );

      res = new Comment { Id = first.Id, Replies = first.Replies.ToList(), User = first.User };
      foreach( var item in first.Replies ) 
      {
         LoadComment( item.Id, item );
      }
   }
   else 
   {
      // You would call your context here and write db.Single(x => x.Id == id).Include(x => x.User.Avatar);
      var child = db.SingleOrDefault( x => x.Id == id );
      if( child == null ) 
      {
         return null;
      }
      com.Replies = new List<Comment>();
      com.Replies.Add( new Comment { Id = child.Id, Replies = child.Replies.ToList(), User = child.User } );
      foreach( var item in child.Replies ) 
      {
         LoadComment( item.Id, com );
      }
   }


   return res;
}

    private static Comment cm1 = new Comment
    {
        Id = 1,
        User = new User { Id = 1, Avatar = new Avatar { Url = "1" } },
        Replies = new List<Comment> {
        new Comment { Id = 2 },
        new Comment { Id = 3 },
        new Comment { Id = 4 },
        new Comment { Id = 5 } },
        Content = "ContentForCommentId1"
    };

    private static Comment cm2 = new Comment
    {
        Id = 2,
        User = new User { Id = 2, Avatar = new Avatar { Url = "2" } },
        Replies = new List<Comment> {
        new Comment { Id = 22 },
        new Comment { Id = 33 },
        new Comment { Id = 44 },
        new Comment { Id = 55 } },
        Content = "ContentForCommentId2"
    };
    private static List<Comment> db = new List<Comment> { cm1, cm2 };

}
Run Code Online (Sandbox Code Playgroud)