1

Linq to objects 式はオブジェクトを返します。オブジェクトは、列挙されるとシーケンスから要素を生成します。通常、遅延 LINQ-to-Object メソッドはパイプラインとして機能するため、シーケンスの各要素は、次の要素が処理される前に処理パイプラインを通過します。

a) しかし、Linq-to-Objects クエリが Linq-to-Entities クエリの結果に対して動作する場合 foreach、反復しようとするとsearch、次の要素が処理される前に、各要素が処理シーケンス全体を再び通過します (つまり、最初の要素です)。 DB から取得されたシーケンスから、Enumerable.Where次に によって処理され、その後にEnumerable.SelectManyのみ DB から次の要素が取得されます)、または DB から一度に取得された要素のセット全体です (foreachシーケンスから最初の要素を読み取ろうとするとき)。 、そして、これらの要素が Linq-to-Objects 演算子の処理パイプラインを通過し始めるのはその後ですか?

        var search = context.Contacts.AsEnumerable().
            Where(s => s.ContactID > 10).SelectMany(s => s.Address);

ありがとうございました

4

1 に答える 1

1

最初は、式 (から) を SQLcontext.Contactsに変換する EF クエリ プロバイダーによって処理されます。IQueryable

その後、 までAsEnumerableに、EF クエリ プロバイダーとのリンクが解除され、それ以降はすべてオブジェクトにリンクされ、前のステートメントの結果セットが処理されます。

ただし、Contact.Address遅延ロードされたコレクションであるためContact、パイプラインを通過するたびに、新しいクエリが発行されて入力されます。これが可能なのは、EF クエリ プロバイダーを介してクエリを実行するゲッターによるContactオーバーライドに、EF がプロキシ型を使用するためです。Address

おそらくご存じのとおり、ステートメント全体を消去すると、EF が 1 つの SQL ステートメントに変換AsEnumerableするツリーに変わります。Expression

于 2012-10-29T21:48:03.450 に答える