web-dev-qa-db-ja.com

遅延読み込みとイーガー読み込み

Entity Frameworkの遅延読み込みは、関連するエンティティの読み込みとアクセスで発生するデフォルトの現象です。ただし、積極的な読み込みは、これらすべての関係を強制的に読み込むことを指します。私は、どのような状況下でイージーローディングがレイジーローディングよりも有益であるかという問題に遭遇しました。これは、遅延読み込みの方がリソースに優しいことは明らかであり、ToList()メソッドを使用しても、遅延読み込みの動作を利用できるためです。ただし、遅延読み込みは実際のデータベースへのリクエストの数を増やす可能性があり、それが開発者がすべてのリレーションを強制的に読み込むためにInlcudeメソッドを使用する理由であると考えました。たとえば、MVC 5でVisual Studioの自動足場を使用する場合、コントローラーで自動的に作成されるIndexメソッドは常にEager Loadingを使用します。その場合、MicrosoftがデフォルトでEager Loadingを使用する理由は常に疑問です。

イージーローディングがレイジーローディングよりも有益な状況で、誰かがレイジーローディングとしてよりリソースフレンドリーな何かがあるのになぜそれを使用するのかを誰かが私に説明してくれれば幸いです。

60
Arrrr

このような関係を分類するのは良いことだと思います

熱負荷を使用する場合

  1. 主エンティティとのあらゆる場所で必ず使用される1対多の関係の「一方」で。記事のユーザープロパティなど。製品のカテゴリプロパティ。
  2. 通常、リレーションが多すぎず、サーバーでのクエリをさらに減らすために、積極的な読み込みが適切な場合です。

遅延読み込みを使用する場合

  1. 1対多の関係のほぼすべての「コレクション側」。ユーザーの記事やカテゴリの製品など
  2. プロパティがすぐに必要になるわけではないことを正確に知っています。

注:トランセンデントは、遅延読み込みには廃棄の問題があるかもしれないと言っていました。

62
farid bekran

Eager Loading: Eager Loadingは、必要なすべてのエンティティを一度にロードするのに役立ちます。つまり、関連オブジェクト(子オブジェクト)は、その親オブジェクトとともに自動的にロードされます。

使用する場合:

  1. リレーションが多すぎない場合は、Eager Loadingを使用します。したがって、サーバーでのクエリをさらに減らすには、Eager Loadingをお勧めします。
  2. どこでもメインエンティティで関連するエンティティを使用することが確実な場合は、イーガーロードを使用します。

遅延読み込み:遅延読み込みの場合、関連オブジェクト(子オブジェクト)は、要求されるまで親オブジェクトと共に自動的に読み込まれません。既定では、LINQは遅延読み込みをサポートしています。

使用する場合:

  1. 1対多のコレクションを使用している場合は、遅延読み込みを使用してください。
  2. 関連するエンティティをすぐに使用していないことが確実な場合は、遅延読み込みを使用してください。

注:Entity Frameworkは、関連データを読み込む3つの方法をサポートしています-イージーロード、レイジーロード、および明示的なロード。

17
Dark Matter

遅延読み込みはいくつかのSQL呼び出しを生成しますが、Eager読み込みは1つの「より重い」呼び出し(結合/サブクエリ)でデータを読み込む場合があります。

たとえば、WebサーバーとSQLサーバーの間に高いpingがある場合、関連するアイテムを遅延読み込みで1行1列で読み込むのではなく、積極的な読み込みを使用します。

16
serhiyb

以下の状況を考慮してください

public class Person{
    public String Name{get; set;}
    public String Email {get; set;}
    public virtual Employer employer {get; set;}
}

public List<EF.Person> GetPerson(){
    using(EF.DbEntities db = new EF.DbEntities()){
       return db.Person.ToList();
    }
}

これで、このメソッドが呼び出された後、Employerエンティティをレイジーロードできなくなります。どうして? dbオブジェクトが破棄されるためです。したがって、強制的にロードするにはPerson.Include(x=> x.employer)を実行する必要があります。

10
Transcendent

Eager Loading一度に複数のエンティティを取得したい場合、たとえば、同じページでユーザーとユーザーの詳細を表示する必要がある場合は、Eager Loadingを使用する必要があります。積極的な読み込みは、データベースでシングルヒットを行い、関連するエンティティを読み込みます。

遅延読み込みページでのみユーザーを表示する必要があり、ユーザーをクリックしてユーザーの詳細を表示する必要がある場合は、遅延読み込みを行う必要があります。遅延読み込みは複数のヒットを作成し、関連エンティティをバインド/反復するときに関連エンティティを読み込みます。

3
Sheriff
// Using LINQ and just referencing p.Employer will lazy load
// I am not at a computer but I know I have lazy loaded in one
// query with a single query call like below.
List<Person> persons = new List<Person>();
using(MyDbContext dbContext = new MyDbContext())
{
    persons = (
        from p in dbcontext.Persons
        select new Person{
            Name = p.Name,
            Email = p.Email,
            Employer = p.Employer
        }).ToList();
}
0
Matt Empringham