私は違いについて混乱しています。.Netはかなり新しいのでIEnumerables
、Linq拡張機能を使用してクエリを実行できます。これは何でIQueryable
、どう違うのですか?
関連項目IQueryable [T]とIEnumerable [T]の違いは何ですか?この質問と重複しています。
私は違いについて混乱しています。.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
メソッドは各メソッドを実行しyield
、メソッドが返した値を取得しますtrue
。
2番目のブロックにx => x.Age > 18
は、式ツリー(Expression<Func<Person, bool>>
)があります。これは「is the 'Age' property> 18」と考えることができます。
これにより、式ツリーを解析して同等のSQLに変換できるため、LINQ-to-SQLなどが存在できるようになります。また、プロバイダーはIQueryable
が列挙されるまで実行する必要がないため(IEnumerable<T>
結局のところ、を実装します)、複数のクエリ演算子を組み合わせて(上記の例Where
とFirstOrDefault
)、基礎となるデータに対してクエリ全体を実行する方法をよりスマートに選択できます。ソース(SELECT TOP 1
SQLでの使用と同様)。
見る:
実際には、LINQ-to-SQLのようなORMを使用している場合
IQueryable
と、クエリはsqlに変換され、データベースサーバーで実行されます。IEnumerable
と、クエリを実行する前に、すべての行がオブジェクトとしてメモリにプルされます。どちらの場合でも、aを呼び出さないToList()
場合ToArray()
、クエリが使用されるたびに実行されるため、IQueryable
クエリがあり、そこから4つのリストボックスに入力すると、データベースに対してクエリが4回実行されます。
また、クエリを拡張する場合:
q.Select(x.name = "a").ToList()
次にIQueryable
、生成されたSQLにはが含まれますがwhere name = "a"
、IEnumerable
さらに多くのロールがデータベースからプルバックされ、x.name = "a"
チェックは.NETによって行われます。
IEnumerable IEnumerableは、メモリ内コレクションでの作業に最適です。IEnumerableはアイテム間を移動せず、前方のみのコレクションです。
IQueryable IQueryableは、データベースやWebサービスなどのリモートデータソースに最適です。IQueryableは、さまざまな興味深い遅延実行シナリオ(ページングや構成ベースのクエリなど)を可能にする非常に強力な機能です。
したがって、メモリ内コレクションを単純に反復処理する必要がある場合は、IEnumerableを使用します。Datasetやその他のデータソースなどのコレクションを操作する必要がある場合は、IQueryableを使用します
主な違いは、IEnumerableは常にすべての要素を列挙するのに対し、IQueryableはクエリに基づいて要素を列挙したり、その他のことを行ったりすることです。クエリは式(.Netコードのデータ表現)であり、IQueryProviderは結果を生成するために、それを調査/解釈/コンパイル/何でも行う必要があります。
クエリ式があると、2つの利点があります。
最初の利点は最適化です。'Where'のような修飾子はクエリ式に含まれているため、IQueryProviderは他の方法では不可能な最適化を適用できます。すべての要素を返し、 'Where'句のためにほとんどの要素を破棄する代わりに、プロバイダーはハッシュテーブルを使用して、指定されたキーを持つアイテムを見つけることができます。
2番目の利点は柔軟性です。式は探索可能なデータ構造であるため、クエリをシリアル化してリモートマシン(たとえば、linq-to-sql)に送信することができます。
IQueriableはIEnumerableと同じですが、Linqでカスタムクエリを実装するための追加機能も提供します。ここにMSDNの説明があります:http : //msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx
まず、IEnumerableはSystem.Collections名前空間にあり、IQueryableはSystem.Linq名前空間にあります。リスト、配列コレクションなどのメモリ内コレクションからデータをクエリするときにIEnumerableを使用し、メモリ外(リモートデータベース、サービスなど)コレクションからデータをクエリする場合は、IQueryableを使用します。IEnumerableは、データベースからデータをクエリしているときに、サーバー側で選択クエリを実行し、クライアント側でメモリ内のデータを読み込み、データをフィルター処理するためです。したがって、より多くの作業を行い、遅くなります。IQueryableは、データベースからデータをクエリするときに、すべてのフィルターを使用してサーバー側で選択クエリを実行します。したがって、実行する作業が少なく、高速になります。