プロバイダーは拡張メソッド IQueryable<>
をサポートしていないため、次のクエリで例外がスローされることを理解しています。Enumerable.TakeWhile
IQueryable<Contact> search = context.Contacts.TakeWhile(q => q.ContactID > 10);
foreach(var q in search); // exception
しかし、C#の観点から前述のクエリを理解しようとすると、混乱します。
上記のチェーンで呼び出される最後のLinqメソッドはLinq-to-Objects であるため、変数はタイプであるTakeWhile
と予想されますが、代わりにタイプIQueryableです(クエリは式ツリーに変換されますが、Linq-to-オブジェクトクエリは基本的に遅延メソッド呼び出しに変換されるため、式ツリー(によって作成された)をメソッド呼び出しに変換しようとしても機能しません。前述のように、これはC#の観点からは混乱を招きます)。 search
IEnumerable<T>
IQueryable<T>
context.Contacts
また、Queryable
演算子がクエリを構築する方法は、を呼び出すことです。IQueryProvider<T>.CreateQuery
これにより、式ツリーIQueryable<T>
が新しいオブジェクトを構築します。これは、どういうわけか、演算子がそれ自体で式ツリーIEnumerable<T>.TakeWhile
を構築することを知っている必要があるか(そうではない)、または呼び出すことができる必要があることを意味しませんか?IQueryProvider<T>.CreateQuery
私の仮定が間違っていると確信しているので、誰かが前のクエリがどのようにしてIQueryable<T>
代わりに型の結果を返すことができるのか説明できますIEnumerable<T>
か?
前もって感謝します