IQueryable と IEnumerable の違いは何ですか
-
19-09-2019 - |
質問
違いが分からず混乱しています。.Net についてはかなり初心者なので、クエリができることはわかっています IEnumerables
Linq 拡張機能を使用します。それで、これは何ですか IQueryable
そしてそれはどのように違うのでしょうか?
こちらも参照 IQueryable[T] と IEnumerable[T] の違いは何ですか? それはこの質問と重複します。
解決
IEnumerable<T>
の前方専用カーソルを表します T
. 。.NET 3.5 では、次のような拡張メソッドが追加されました。 LINQ standard query operators
のように Where
そして First
, 、述語または匿名関数を必要とする演算子を使用します。 Func<T>
.
IQueryable<T>
同じ LINQ 標準クエリ演算子を実装しますが、 Expression<Func<T>>
述語と匿名関数の場合。 Expression<T>
これはコンパイルされた式ツリーであり、クエリ可能なプロバイダーによって解析され、それに応じて使用できるメソッドの分割バージョン (いわば「半分コンパイルされた」) です。
例えば:
IEnumerable<Person> people = GetEnumerablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();
IQueryable<Person> people = GetQueryablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();
最初のブロックでは、 x => x.Age > 18
は匿名メソッド (Func<Person, bool>
)、他のメソッドと同様に実行できます。 Enumerable.Where
メソッドは各人に対して 1 回実行されます。 yield
メソッドが返した値を取得する true
.
2番目のブロックでは、 x => x.Age > 18
は式ツリー (Expression<Func<Person, bool>>
)、これは「'Age' プロパティ > 18」であると考えることができます。
これにより、式ツリーを解析して同等の SQL に変換できるため、LINQ-to-SQL のようなものが存在できるようになります。また、プロバイダーは実行されるまで実行する必要がないため、 IQueryable
列挙されています(実装されています) IEnumerable<T>
, 結局のところ)、複数のクエリ演算子を組み合わせることができます (上記の例では Where
そして FirstOrDefault
)基になるデータ ソースに対してクエリ全体を実行する方法についてより賢明な選択を行うため(たとえば、 SELECT TOP 1
SQL)。
見る:
他のヒント
実際には、LINQ-to-SQL のような ORM を使用している場合
- を作成する場合は、
IQueryable
, 、その後、クエリは SQL に変換され、データベース サーバー上で実行される可能性があります。 - を作成する場合は、
IEnumerable
, その後、クエリを実行する前に、すべての行がオブジェクトとしてメモリに取り込まれます。
どちらの場合も、電話をかけなければ、 ToList()
または ToArray()
そうすれば、クエリは使用されるたびに実行されます。つまり、 IQueryable
そこから 4 つのリスト ボックスに値を入力すると、データベースに対してクエリが 4 回実行されます。
また、クエリを拡張すると、次のようになります。
q.Select(x.name = "a").ToList()
それから、 IQueryable
生成された SQL には以下が含まれます where name = "a"
, 、しかし、 IEnumerable
さらに多くのロールがデータベースから取得され、その後、 x.name = "a"
チェックは.NETによって行われます。
」の主な違いは、のIQueryableのために定義された拡張メソッドは、それが受け取るデリゲートは、式ツリーの代わりに呼び出すための方法である意味、代わりのFuncオブジェクトのオブジェクト表現を取ることである。IEnumerableをは、メモリ内のコレクションでの作業に最適です、しかし、のIQueryableは、データベースやWebサービス "
のように、リモートデータソースすることができますソース:ここを
IEnumerable IEnumerable は、メモリ内コレクションを操作するのに最適です。IEnumerable は項目間を移動せず、前方のみのコレクションです。
IQueryableIQueryable は、データベースや Web サービスなどのリモート データ ソースに最適です。IQueryable は、さまざまな興味深い遅延実行シナリオ (ページングや構成ベースのクエリなど) を可能にする非常に強力な機能です。
したがって、単にメモリ内のコレクションを反復処理する必要がある場合は IEnumerable を使用し、Dataset やその他のデータ ソースなどのコレクションを操作する必要がある場合は IQueryable を使用します。
原則違いは、のIQueryableは、クエリに基づいて、要素を列挙し、あるいは他のことを行いますながらIEnumerableをは、すべての時間のすべての要素を列挙することです。クエリはIQueryProviderは/コンパイル/解釈/探索しなければならない式(.NETコードのデータ表現)であり、どのような結果を生成するために
クエリ式を持つことは、2つの利点が得られます。
最初の利点は、最適化です。修飾子クエリ式に含まれている「どこが好きなので、IQueryProviderは、そうでない場合は不可能な最適化を適用することができます。代わりに、すべての要素を返すため、「どこ」節にそれらのほとんどを捨てるのは、プロバイダが指定したキーを持つ項目を見つけるためにハッシュテーブルを使用することができます。
第2の利点は、柔軟性があります。式は、探索可能なデータ構造であるため、あなたが(例えば、LINQからSQLへ)クエリをシリアル化し、リモートマシンに送るようなことを行うことができます。
IQueriableはIEnumerableをと同じですが、それはまた、LINQのクエリを実行してカスタム実装するための追加機能を提供します。 http://msdn.microsoft:ここでは、MSDNの説明があります。 COM / EN-US /ライブラリ/ system.linq.iqueryable.aspxする
まずIEnumerableをはにSystem.Collections名前空間に見出されます。リスト、配列のコレクションなどのようなメモリ内のコレクションからデータを照会するときに(リモートデータベース、サービスのように)、アウトメモリからデータを照会するとき、コレクションあなたがIEnumerableを使用している場合は、のIQueryableを使用しているので。データベースからデータを照会するためながら、IEnumerableをは、メモリ内のクライアント側、サーバ側の負荷データを選択クエリを実行し、データをフィルタリングします。したがって、より多くの仕事をし、遅くなります。データベースからデータを照会しながら、のIQueryableは、すべてのフィルタを使用してサーバー側で選択クエリを実行します。したがって、以下の作業を行い、速くなります。