web-dev-qa-db-ja.com

Entity Framework 4.1 POCO Code Firstでは、仮想キーワードはどのような効果がありますか?

virtualキーワードは、EF Code Firstのプロパティで使用すると効果がありますか?誰かが異なる状況でのそのすべての影響を説明できますか?

たとえば、 lazy loading -ICollection/one-to-many関係プロパティで仮想キーワードを使用すると、デフォルトで遅延ロードされますが、仮想キーワードが出力されると、熱心に読み込まれます。

virtualキーワードは、POCOエンティティを使用したEFで他にどのような効果がありますか?すべてのプロパティでvirtualを使用するようにデフォルトにするか、デフォルトで使用しないようにする必要がありますか?

217
Scott Stafford

これまでのところ、私はこれらの効果を知っています。

  • 遅延読み込み :特に指定しない限り、virtual ICollectionは遅延読み込みされます。
  • より効率的な変更追跡 。以下のすべての要件を満たしている場合、変更追跡では、仮想プロパティをフックすることにより、より効率的な方法を使用できます。リンクから:

    変更追跡プロキシを取得するための基本的なルールは、クラスがパブリック、非抽象、または非密閉でなければならないということです。また、クラスは、永続化されるすべてのプロパティに対してパブリック仮想ゲッター/セッターを実装する必要があります。最後に、コレクションベースの関係ナビゲーションプロパティをICollection<T>のみとして宣言する必要があります。具体的な実装や、ICollection<T>から派生した別のインターフェイス(遅延読み込みプロキシとの違い)にすることはできません

これを説明する別の便利なリンクは、MSDNの POCOプロキシを作成するための要件 です。

187
Scott Stafford

この仮想キーワードは、エンティティフレームワークからのデータの読み込み(遅延読み込み、熱心な読み込み、明示的な読み込み)のトピックに関連しています。

遅延読み込みでデータを読み込む場合は、virtualキーワードを使用する必要があります。

lazy loadingは、エンティティまたはエンティティのコレクションが最初にアクセスされたときにデータベースから自動的にロードされるプロセスです。

たとえば、次に定義するBlogエンティティクラスを使用する場合、関連する投稿は、投稿ナビゲーションプロパティに最初にアクセスしたときに読み込まれます。

public class Blog 
{  
     public int BlogId { get; set; }  
     public string Name { get; set; }  
     public string Url { get; set; }  
     public string Tags { get; set; }  
     public virtual ICollection<Post> Posts { get; set; }  
}

Postsプロパティの非仮想化により、Postsコレクションの遅延読み込みをオフにできます。

遅延読み込みがオフの場合、Postsコレクションの読み込みは、積極的な読み込み(Includeメソッドを使用)または関連エンティティの明示的な読み込み(Loadメソッドを使用)を使用して実行できます。

熱心に読み込み中:

using (var context = new BloggingContext()) 
{ 
    // Load all blogs and related posts 
    var blogs1 = context.Blogs 
                          .Include(b => b.Posts) 
                          .ToList(); 
}

明示的な読み込み:

using (var context = new BloggingContext()) 
{ 
    var blog = context.Blogs.Find(1); 

    // Load the posts related to a given blog 
    context.Entry(blog).Collection(p => p.Posts).Load(); 
}
57
Parsa