在EF Core中實現遞歸屬性加載

asp.net-core c# entity-framework 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文檔中的“ 加載相關數據”頁面非常有用,但我不確定如何最好地處理此問題。我已經嘗試將一些東西放在一起,但我無法概念化如何將它們整合在一起。再次注意:我正在使用EF Core 1.1.0,因此我可以訪問“顯式加載”部分中的函數。

如果給出父評論的ID,我如何加載整個評論樹?

一般承認的答案

我沒有數據庫,所以我只是在內存中做了,但如果你按照我的意見,它將適合你。注意我在內存中的對象,只有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 };

}

熱門答案

為什麼不使用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"

我希望它對你有所幫助。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow