IQueryableとIEnumerableの違いは何ですか


回答:


186

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>結局のところ、を実装します)、複数のクエリ演算子を組み合わせて(上記の例WhereFirstOrDefault)、基礎となるデータに対してクエリ全体を実行する方法をよりスマートに選択できます。ソース(SELECT TOP 1SQLでの使用と同様)。

見る:


1
かなり簡単な答え
アシュヴェリ

83

実際には、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によって行われます。


"クエリはsqlに変換される可能性があります": 'may be'を取得できませんでした。また、IEnumerableがあり、「複雑なチェーン」を作成した場合、(明らかに)IQueryableとは異なり、「最適化された」SQLクエリに変換されません。「すべての行がメモリに読み込まれる」と言ったときの意味を確認したいだけです。2つのwhere句があるとします。エンティティのすべてのタプルが最初にメモリにフェッチされ、次に通常の「メモリ内」フィルタリングが行われますか?
Vaibhav 2015

36

「主な違いは、IQueryableに対して定義された拡張メソッドが、FuncオブジェクトではなくExpressionオブジェクトをとるということです。つまり、受け取るデリゲートは、呼び出すメソッドではなく、式ツリーです。IEnumerableは、メモリ内コレクションの操作に最適ですが、IQueryableにより、データベースやWebサービスなどのリモートデータソース用」

出典:こちら


19

IEnumerable IEnumerableは、メモリ内コレクションでの作業に最適です。IEnumerableはアイテム間を移動せず、前方のみのコレクションです。

IQueryable IQueryableは、データベースやWebサービスなどのリモートデータソースに最適です。IQueryableは、さまざまな興味深い遅延実行シナリオ(ページングや構成ベースのクエリなど)を可能にする非常に強力な機能です。

したがって、メモリ内コレクションを単純に反復処理する必要がある場合は、IEnumerableを使用します。Datasetやその他のデータソースなどのコレクションを操作する必要がある場合は、IQueryableを使用します


11

主な違いは、IEnumerableは常にすべての要素を列挙するのに対し、IQueryableはクエリに基づいて要素を列挙したり、その他のことを行ったりすることです。クエリは式(.Netコードのデータ表現)であり、IQueryProviderは結果を生成するために、それを調査/解釈/コンパイル/何でも行う必要があります。

クエリ式があると、2つの利点があります。

最初の利点は最適化です。'Where'のような修飾子はクエリ式に含まれているため、IQueryProviderは他の方法では不可能な最適化を適用できます。すべての要素を返し、 'Where'句のためにほとんどの要素を破棄する代わりに、プロバイダーはハッシュテーブルを使用して、指定されたキーを持つアイテムを見つけることができます。

2番目の利点は柔軟性です。式は探索可能なデータ構造であるため、クエリをシリアル化してリモートマシン(たとえば、linq-to-sql)に送信することができます。



1

まず、IEnumerableはSystem.Collections名前空間にあり、IQueryableはSystem.Linq名前空間にあります。リスト、配列コレクションなどのメモリ内コレクションからデータをクエリするときにIEnumerableを使用し、メモリ外(リモートデータベース、サービスなど)コレクションからデータをクエリする場合は、IQueryableを使用します。IEnumerableは、データベースからデータをクエリしているときに、サーバー側で選択クエリを実行し、クライアント側でメモリ内のデータを読み込み、データをフィルター処理するためです。したがって、より多くの作業を行い、遅くなります。IQueryableは、データベースからデータをクエリするときに、すべてのフィルターを使用してサーバー側で選択クエリを実行します。したがって、実行する作業が少なく、高速になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.