2016-08-08 5 views
1

私はthis answerを読んでいましたが、IQueryableのメモリ内ライフサイクルでどれくらいの負荷がかかるか分かりません。それはメモリ内のデータをロードしないあなたはIncludeからの復帰を列挙していない場合はeagerインクルード関数はメモリ内のデータを呼び出しますか?

Customer 
    Order 
    Order 
    Order 

は、このようなオブジェクトグラフを生成する、あなたはdb.Customers.Include("Orders")を持って言いますか?ある

IQueryable<Customer> customersWithOrders = db.Customers.Include("Orders"); 

Customerコレクション(と彼のOrders)が熱心に含まOrdersにより、インメモリ持ち込まれたことを意味していますか?または、「熱意」とは、Customerコレクションが列挙されている場合、注文がメモリ内に持ち込まれることを意味しますか?

答えて

2

ここでは2つのことが起こっています。まず、そのクエリの実行を必要とする操作が行われるまで、クエリはデータベースに送信されません。たとえば、次のような場合:

var foos = db.Foos.Where(...); 

実際にはまだクエリは発行されていません。しかし、次のような場合は、

foreach (var foo in foos) 
{ 
    ... 
} 

を入力して、データベースにクエリを送信します。クエリが実行されるその他の要素は、ToList()Count()などです。基本的には、実際のデータが必要なときはいつでも、Entity Frameworkのみがクエリを送信します。

次に、eagerとlazyローディングの概念はまったく別です。これは約関連のの項目であり、基本的にEntity Frameworkがクエリの一部として1つ以上の結合を発行するかどうかについてです。 Include()を使用することで、Entity Frameworkにその関係の結合を発行するように指示します。繰り返しますが、評価(反復、列挙、カウントなど)が行われるまでクエリは発行されませんが、評価すると、エンティティのセットと関連エンティティの両方が一度にすべてプルされます。

リレーションシップを含めない場合は、レイジーローディングにフォールバックします。つまり、リレーションシップは何らかの方法でアクセスしない限り、マテリアライズされません。これは、いくつかの点で最初のクエリがどのように機能するかと同様です。関連項目は、データが実際に必要とされる時点でのみ取得されます。それ以外の場合は問合せは発行されません。ただし、これは完全に別のクエリになります。

長いと短いので、必要なデータと必要なときに注意する必要があります。関連するエンティティを利用する場合は、の前にを含める必要がありますが、いずれの方法でも、そのデータが必要な場合にのみクエリが送信されます。

2

Eager Loadingは、基本となるクエリのみを変更します。そのため、複数のコール(およびLINQの遅延実行の性質に依存する他のLINQコール)をチェーン化することもできます。

データソースから列挙されるときにのみ、データが明示的に要求されます。

更新(@Ehsan SAJJADコメントごとなど):クエリはすでにマテリアライズされていても、遅延ロードで

、で、ナビゲーションプロパティ(Orderforeachまたは例えばToList()を使用して)この場合)は、データソースにアクセスする際にのみ要求されます。

+0

どのような違いは、次に熱意と怠惰なB/Wですか? –

関連する問題