Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
503 views
in Technique[技术] by (71.8m points)

c# - Implementing recursive property loading in EF Core

I'm on .NET Core 1.1.0, EF Core 1.1.0, VS 2015.

I'm writing a system for posts/comments, and I need a function to load a comment and all of its children and their associated properties. Here's a simplified version of my classes:

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

Any given comment can have any number of replies:

-PARENT
    -CHILD 1
    -CHILD 2
        -CHILD 3
    -CHILD 4
    -CHILD 5
        -CHILD 6
            -CHILD 7

So, given the ID of the parent comment, I need to load the entire tree, including users and their respective avatars. (I have controls elsewhere to make sure these trees don't become unwieldy, I'm not concerned at this point about potentially grabbing way too much data.)

The Loading Related Data page in the EF Core docs is very helpful, but I'm not sure how to best handle this. I've experimented putting some things together but I just can't conceptualize how to fit it all together. To note again: I'm using EF Core 1.1.0, so I do have access to the functions in the "Explicit loading" section.

How can I load the entire tree of comments given a parent comment's ID?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I do not have a database so I just did it in memory but if you follow my comments, it will work for you. Notice the objects I have in memory, only comment with id 2 has replies.

LoadComment method is where everything happens. The rest is just setup code I needed.

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

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...