回答:
まず、インターフェースを拡張します。「プレーン」で実行できることは何でも、でも実行できます。IQueryable<T>
IEnumerable<T>
IEnumerable<T>
IQueryable<T>
IEnumerable<T>
ちょうど持ってGetEnumerator()
返すメソッドEnumerator<T>
あなたがその呼び出せるためMoveNext()
のシーケンスを反復処理する方法をTを。
どのようなIQueryable<T>
ことはしていIEnumerable<T>
ないん特に-1とポイント2つのプロパティで、クエリプロバイダ(例えば、SQLプロバイダへのLINQ)との別のポインティングクエリ式表すIQueryable<T>
ことができ、実行時-たどれる抽象構文木などのオブジェクトを指定されたクエリプロバイダーによって理解されます(ほとんどの場合、例外がスローされない限り、LINQ to SQL式をLINQ to Entitiesプロバイダーに渡すことはできません)。
式は、単にオブジェクト自体の定数式、またはクエリ演算子とオペランドの組み合わせセットのより複雑なツリーにすることができます。クエリプロバイダーのIQueryProvider.Execute()
またはIQueryProvider.CreateQuery()
メソッドは、それに渡される式で呼び出され、クエリ結果または別の結果IQueryable
がそれぞれ返されます。
AsQueryable()
enumerableをqueryableにキャストし、IQueryable
インターフェイスを実装している場合はそれを返します。それ以外の場合ConstantExpression
は、返されたEnumerableQuery
オブジェクトで参照されて いるにラップします。
主な違いは、デリゲートの代わりにオブジェクトをIQueryable<T>
受け取るためのLINQ演算子ですExpression
。つまり、それが受け取るカスタムクエリロジック(述語や値セレクターなど)は、メソッドへのデリゲートではなく、式ツリーの形式です。
IEnumerable<T>
インメモリで反復されるシーケンスを操作するのに最適ですが、 IQueryable<T>
データベースやWebサービスなどのリモートデータソースのようなメモリ不足を可能にします。クエリの実行が「インプロセス」で実行される場合、通常必要なのは、クエリの各部分を実行するためのコード(コードとして)だけです。
実行がアウトプロセスで実行される場合、LINQプロバイダーがそれをメモリ不足の実行に適した形式に変換できるように、クエリのロジックをデータで表す必要があります。これがLDAPクエリであっても、 SQLなど。
でより多くの:
これは、これらのインターフェースがどのように異なるかを示すYouTubeの素晴らしいビデオで、一見の価値があります。
以下は、それについての長い説明的な回答です。
最初に覚えておかなければならない重要な点は、IQueryable
インターフェイスがから継承することです。IEnumerable
そのためIEnumerable
、IQueryable
できることは何でもできます。
多くの違いがありますが、最大の違いをもたらす1つの大きな違いについて説明します。IEnumerable
インターフェースは、コレクションがLINQ
やEntityフレームワークを使用して読み込まれ、コレクションにフィルターを適用する場合に便利です。
IEnumerable
エンティティフレームワークで使用する以下の単純なコードを考えます。使用していますWhere
そのレコードを取得するには、フィルタをEmpId
あるが2
。
EmpEntities ent = new EmpEntities();
IEnumerable<Employee> emp = ent.Employees;
IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
このフィルタは、IEnumerable
コードがあるクライアント側で実行されます。つまり、すべてのデータはデータベースからフェッチされ、クライアントでスキャンされてEmpId
isでレコードが取得されます2
。
しかし、今、我々が変更されている以下のコードを参照IEnumerable
するにIQueryable
。サーバー側でSQLクエリを作成し、必要なデータのみをクライアント側に送信します。
EmpEntities ent = new EmpEntities();
IQueryable<Employee> emp = ent.Employees;
IQueryable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
だから、違いIQueryable
とはIEnumerable
、フィルタロジックが実行される場所についてです。1つはクライアント側で実行され、もう1つはデータベースで実行されます。
したがって、メモリ内のデータ収集のみで作業するIEnumerable
場合は適切ですが、データベースに接続されているデータ収集をクエリする場合は、ネットワークトラフィックを減らし、SQL言語の機能を使用するため、IQueryableの方が適しています。
IEnumerable: IEnumerableは、メモリ内コレクション(またはローカルクエリ)の操作に最適です。IEnumerableはアイテム間を移動せず、前方のみのコレクションです。
IQueryable: IQueryableは、データベースやWebサービス(またはリモートクエリ)などのリモートデータソースに最適です。IQueryableは、さまざまな興味深い遅延実行シナリオ(ページングや構成ベースのクエリなど)を可能にする非常に強力な機能です。
したがって、メモリ内コレクションを単純に反復処理する必要がある場合は、IEnumerableを使用します。Datasetやその他のデータソースなどのコレクションを操作する必要がある場合は、IQueryableを使用します。
実際には、LINQ-to-SQLのようなORMを使用している場合
どちらの場合も、あなたが呼び出していない場合ToList()
やToArray()
、クエリは、それが使用されるたびに実行されますので、たとえば、あなたが持っているIQueryable<T>
、あなたは、クエリがデータベース4回に対して実行されます、それから4つのリストボックスを埋めます。
また、クエリを拡張する場合:
q.Where(x.name = "a").ToList()
次に、IQueryableを使用すると、生成されたSQLに "where name =" a "が含まれますが、IEnumerableを使用すると、さらに多くのロールがデータベースから取得され、x.name =" a "チェックが.NETによって行われます。
下記の小さなテストは、IQueryable<T>
との違いの1つの側面を理解するのに役立ちますIEnumerable<T>
。他の誰かの投稿に修正を加えようとしたこの投稿からこの回答を再現しました
次の構造をDBに作成しました(DDLスクリプト):
CREATE TABLE [dbo].[Employee]([PersonId] [int] NOT NULL PRIMARY KEY,[Salary] [int] NOT NULL)
次に、レコード挿入スクリプト(DMLスクリプト)を示します。
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(1, 20)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(2, 30)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(3, 40)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(4, 50)
INSERT INTO [EfTest].[dbo].[Employee] ([PersonId],[Salary])VALUES(5, 60)
GO
現在、私の目標はEmployee
、データベースのテーブルから上位2レコードを取得することでした。Employee
データベースのテーブルを指すADO.NET Entity Data Modelアイテムをコンソールアプリケーションに追加し、LINQクエリの作成を開始しました。
IQueryableルートのコード:
using (var efContext = new EfTestEntities())
{
IQueryable<int> employees = from e in efContext.Employees select e.Salary;
employees = employees.Take(2);
foreach (var item in employees)
{
Console.WriteLine(item);
}
}
このプログラムの実行を開始したとき、SQL ServerインスタンスでSQLクエリプロファイラーのセッションも開始していました。実行の概要を次に示します。
SELECT TOP (2) [c].[Salary] AS [Salary] FROM [dbo].[Employee] AS [c]
それはそれだけでIQueryable
適用するスマート十分であるTop (2)
ことはワイヤ上5つのレコードのうちの2つだけをもたらすように、データベース・サーバー側自体に句を。クライアントコンピューター側では、それ以上のインメモリフィルタリングはまったく必要ありません。
IEnumerableルートのコード:
using (var efContext = new EfTestEntities())
{
IEnumerable<int> employees = from e in efContext.Employees select e.Salary;
employees = employees.Take(2);
foreach (var item in employees)
{
Console.WriteLine(item);
}
}
この場合の実行の概要:
SELECT [Extent1].[Salary] AS [Salary]
FROM [dbo].[Employee] AS [Extent1]
これで、テーブルにIEnumerable
存在する5つのレコードすべてSalary
が取得され、クライアントコンピュータでメモリ内フィルタリングが実行され、上位2つのレコードが取得されました。そのため、より多くのデータ(この場合は3つの追加レコード)が不必要にネットワーク経由で転送されました。
これは私が(このトピックについて)同様の投稿で書いたものです。(いいえ、私は通常自分自身を引用しませんが、これらは非常に良い記事です。)
「この記事は役に立ちます: LINQ-to-SQLでのIQueryableとIEnumerableの比較です。
その記事を引用すると、「MSDNドキュメントによると、IQueryableで行われた呼び出しは、代わりに内部式ツリーを構築することによって機能します。「IQueryable(Of T)を拡張するこれらのメソッドは、直接クエリを実行しません。代わりに、それらの機能は、累積クエリを表す式ツリーであるExpressionオブジェクトを構築することです。
式ツリーは、C#および.NETプラットフォームで非常に重要な構成要素です。(それらは一般的に重要ですが、C#はそれらを非常に便利にします。)違いをよりよく理解するために、公式のC#5.0仕様の式とステートメントの 違いについて読むことをお勧めします。ラムダ計算に分岐する高度な理論的概念の場合、式により、ファーストクラスのオブジェクトとしてのメソッドのサポートが可能になります。IQueryableとIEnumerableの違いは、この点に集中しています。IQueryableは式ツリーを構築しますが、IEnumerableは、少なくともMicrosoftの秘密のラボで作業していない私たちにとってはそうではありません。
ここでは、プッシュとプルの観点からの違いを詳しく説明する、もう1つの非常に役立つ記事を紹介します。(「プッシュ」と「プル」では、データフローの方向を指します。.NETおよびC#のリアクティブプログラミングテクニック
ここでは、ステートメントラムダと式ラムダの違いを詳しく説明し、式の構造の概念をより深く説明する非常に優れた記事を紹介します。C #デリゲート、式ツリー、ラムダステートメントとラムダ式の比較。」
データベースから取得したデータを使用IEnumerable
しIQueryable
て操作します。IQueryable
はから継承するIEnumerable
ためIQueryable
、すべてのIEnumerable
機能が含まれます。主な違いIQueryable
とはIEnumerable
つまりIQueryable
、一方、フィルタを使用して実行クエリIEnumerable
最初のクエリが実行され、それが条件に基づいてデータをフィルタリングします。
以下のより詳細な差別化を見つけてください:
IEnumerable
IEnumerable
System.Collections
名前空間に存在するIEnumerable
サーバー側で選択クエリを実行し、クライアント側でメモリ内のデータを読み込み、データをフィルター処理するIEnumerable
List、Arrayなどのメモリ内コレクションからのデータのクエリに適していますIEnumerable
LINQ to ObjectおよびLINQ to XMLクエリに有益IQueryable
IQueryable
System.Linq
名前空間に存在するIQueryable
すべてのフィルターを使用してサーバー側で「選択クエリ」を実行しますIQueryable
アウトメモリ(リモートデータベース、サービスなど)コレクションからのデータのクエリに適していますIQueryable
LINQ to SQLクエリに有益したがってIEnumerable
、通常はメモリ内コレクションのIQueryable
処理に使用されますが、コレクションの操作には一般的に使用されます。
IEnumerableとIQueryableの両方を使用して、データのコレクションを保持し、データのコレクションに対するフィルタリングなどのデータ操作操作を実行します。ここで、例との最良の比較を見つけることができます。 http://www.gurujipoint.com/2017/05/difference-between-ienumerable-and.html
ienumerable:インプロセスメモリを処理する場合、つまりデータ接続なしiqueryable:SQLサーバーを処理する場合、つまりデータ接続ilistを使用する場合:オブジェクトの追加、オブジェクトの削除などの操作