2011-11-11 18 views
2

私はPOCOオブジェクトでエンティティフレームワークを使用しています.LazyLoadingが有効になっています。Entity Framework 4レイジーローディングエンティティセット

オブジェクトに関連付けられたコレクションで作業している場合、コレクションはいつ完全にロードされ、どのような状況になりますか?

私はこれらの

Order.OrderItems.Count() 
Order.OrderItems.Any(x => x.StatusId = aValue) 
Order.OrderItems.All(x => x.StatusId = aValue) 

のそれぞれを呼び出す場合、これらのいずれかがのOrderItemsコレクションの完全な読み込みを保証していますか?

を照会した後

context.LoadProperty(order, “OrderItems”) 

を問い合わせる場合、またはコード内のポイントで 我々は

Order.Include(“OrderItems”) 

を呼んでいる。しかし、私は時々、これは常に起こっていません実現してきた - と私が知りたいですこれの結果は起こらない。私は、一般的に、あなたはそれらの結果の上に、または追加 foreach ToListは、 ToArrayは、などこれはにどのようにLINQのどちらかになるまで、あなたのデータをロードしないこと

答えて

4

LINQのメソッドと知識のギャップのビットを持っていると思いますエンティティプロバイダを使用すると、メソッドを連鎖させ、最終構造体に対してのみクエリを構築することができます。

メソッドがIQueryableまたはIEnumerableを返す場合、Linqがその時点でデータをロードしないことを確かめることができます。 LINQのは、ブール値または整数を返さなければならないならば、それはすぐにあなたのクエリを実行しなければならない最も外側のクエリのために

Order.OrderItems.Count() 
Order.OrderItems.Any(x => x.StatusId = aValue) 
Order.OrderItems.All(x => x.StatusId = aValue) 

、:

しかし。しかし、ネストされたクエリは、外部クエリが評価されるまで評価されないため、ネストされたクエリでは少し複雑になります。

について:私はIncludeは、独自のクエリを解決しないであろうと信じて

Order.Include("OrderItems") 

。別のクエリを作成しているときに追加のデータにピギーバックするために使用します。あなたがこの記事のセットをチェックアウトすることができ、一般的な

LINQのあなたはLINQのは、どのように動作するか(一般的に)知りたい場合は、:

http://msmvps.com/blogs/jon_skeet/archive/tags/Edulinq/default.aspx

あなたのアイデアを与えるだろうIEnumerableを延期することができ、評価が必要な場合。 Linq to Entitiesプロバイダーに関するすべてのことを教えてくれるわけではありませんが、知識のかなりの部分が移転します。

+0

ありがとう@Merlyn Morgan-Graham。 'Linqがブール値または整数を返す必要がある場合は、すぐにクエリを実行する可能性があることを明確にしてください。'私はhttp://msmvps.com/blogs/jon_skeet/archive/2010/12/28/reimplementing-linq-to-objects-part-10-any-and-all.aspxを見てきました。すべては実際にカバーの下の結果を反復するので、自動的にコレクションを実現します。だからAny/Allが外側のクエリでコレクションをロードするかのようです。 –

+1

@TimBrown: "AnyとAllは実際にはカバーの下の結果を反復するので、コレクションを自動的に実現します。"私はこれが私が言ったこととまったく同じだと思う、ちょうどweasel-speak( "おそらく" = **常に**、笑)。私はちょうどそれがうまくいけばその文をクリアした編集をしました。 –

+0

また、ネストされたクエリによって、私は 'Order.OrderItems.Where(i => i.Rebates.Any())'のようなものを意味します - 'Rebates.Any()'は外部クエリが評価される。 –

3
Order.OrderItems.Any(x => x.StatusId = aValue) 
Order.OrderItems.All(x => x.StatusId = aValue) 

はクエリです。

これらのクエリは、.ToList()(または他のイテレータをオブジェクトに変換するために)を呼び出すと実行されます。.Includeを使用すると、クエリを実行すると、含まれているプロパティが設定されます(クエリにはそのテーブルの結合が含まれます)。 AnyまたはAll(またはWhereのような任意のフィルター拡張子)を使用すると、条件(別の表にある可能性があります)が追加されますが、OrderItemsはsql selectに入れられませんので、.Includeを使用しない限りロードされません。

- あなたの質問に関連していない

が、あなたはこれで新鮮で、そしてあなたがページングを持っている場合、(クエリを実行)ToListを呼び出す前に、あなたのクエリにSkipTakeを追加することを忘れないでください、私は人々を見てきましたToListを呼び出し、ページングを行う前にテーブル全体をメモリに読み込みます。

+0

+1のページングアドバイス。本当に?私は、ページングを実装しようとすると、特にSkipとTakeのようなものを探し出すだろうと考えました。それがLinqの全ポイントです。奇妙な... :) –

+0

多くの場合、仕様がなく、プロトタイプを作成するときに "ページングが利用できません"という指示があります。その後、そのプロトタイプはリリースされ、xxレコードがあると、「グリッドはあまりにも多くの領域を占有する」とページングを追加するという指示があります。 linqがどのように動作するのかわからない新規の開発者は、コントローラ/コードビハインドにある変数にSkip/Takeを追加するだけでよく、テーブル全体を含む変数は認識しません。これは、linq(foreachループの "サブクエリ"を想像してください:)の誤った使用法から現れるパフォーマンスの問題の中で最も簡単です。 –

+0

ありがとうございます@Goran Obradovicさんのコメントありがとうございます。 'これらのクエリは、呼び出したときに実行されます.ToList()'は、ブール値またはintを返すメソッドがコレクションをロードするという最初の回答と矛盾するようです。私が誤解した場合にはお詫び申し上げます。矛盾はありますか? –

関連する問題