EFコアでの再帰的なプロパティロードの実装

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を使用しているので、 "Explicit loading"セクションの関数にアクセスできます。

親コメントの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 };

}

人気のある回答

あなたは熱心な読み込みを使わないのはなぜですか?複数のレベルを熱心に読み込んでいます.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
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ