Entity Frameworkの遅延読み込みは、関連するエンティティの読み込みとアクセスで発生するデフォルトの現象です。ただし、積極的な読み込みは、これらすべての関係を強制的に読み込むことを指します。私は、どのような状況下でイージーローディングがレイジーローディングよりも有益であるかという問題に遭遇しました。これは、遅延読み込みの方がリソースに優しいことは明らかであり、ToList()
メソッドを使用しても、遅延読み込みの動作を利用できるためです。ただし、遅延読み込みは実際のデータベースへのリクエストの数を増やす可能性があり、それが開発者がすべてのリレーションを強制的に読み込むためにInlcude
メソッドを使用する理由であると考えました。たとえば、MVC 5でVisual Studioの自動足場を使用する場合、コントローラーで自動的に作成されるIndexメソッドは常にEager Loadingを使用します。その場合、MicrosoftがデフォルトでEager Loadingを使用する理由は常に疑問です。
イージーローディングがレイジーローディングよりも有益な状況で、誰かがレイジーローディングとしてよりリソースフレンドリーな何かがあるのになぜそれを使用するのかを誰かが私に説明してくれれば幸いです。
このような関係を分類するのは良いことだと思います
熱負荷を使用する場合
遅延読み込みを使用する場合
注:トランセンデントは、遅延読み込みには廃棄の問題があるかもしれないと言っていました。
Eager Loading: Eager Loadingは、必要なすべてのエンティティを一度にロードするのに役立ちます。つまり、関連オブジェクト(子オブジェクト)は、その親オブジェクトとともに自動的にロードされます。
使用する場合:
遅延読み込み:遅延読み込みの場合、関連オブジェクト(子オブジェクト)は、要求されるまで親オブジェクトと共に自動的に読み込まれません。既定では、LINQは遅延読み込みをサポートしています。
使用する場合:
注:Entity Frameworkは、関連データを読み込む3つの方法をサポートしています-イージーロード、レイジーロード、および明示的なロード。
遅延読み込みはいくつかのSQL呼び出しを生成しますが、Eager読み込みは1つの「より重い」呼び出し(結合/サブクエリ)でデータを読み込む場合があります。
たとえば、WebサーバーとSQLサーバーの間に高いpingがある場合、関連するアイテムを遅延読み込みで1行1列で読み込むのではなく、積極的な読み込みを使用します。
以下の状況を考慮してください
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)
を実行する必要があります。
Eager Loading一度に複数のエンティティを取得したい場合、たとえば、同じページでユーザーとユーザーの詳細を表示する必要がある場合は、Eager Loadingを使用する必要があります。積極的な読み込みは、データベースでシングルヒットを行い、関連するエンティティを読み込みます。
遅延読み込みページでのみユーザーを表示する必要があり、ユーザーをクリックしてユーザーの詳細を表示する必要がある場合は、遅延読み込みを行う必要があります。遅延読み込みは複数のヒットを作成し、関連エンティティをバインド/反復するときに関連エンティティを読み込みます。
// 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();
}