web-dev-qa-db-ja.com

List()の代わりにAsQueryable()を使用する理由

Entity Framework および [〜#〜] linq [〜#〜] を使用したデータアクセスにリポジトリパターンを使用するようになりました。 -テストリポジトリ。私が見るほとんどのサンプルは、呼び出しがList <T>ではなくNレコードを返すときにAsQueryable()を返します。これを行う利点は何ですか?

55
Keith Adler

AsQueryableは、リストを取得するために必要な指示であるクエリを作成するだけです。データベースレベルまで送信される新しいWhere句を追加するなど、後でクエリにさらに変更を加えることができます。

AsListは、メモリ内のすべてのアイテムを含む実際のリストを返します。新しいWhere句を追加すると、データベースが提供する高速フィルタリングが得られません。代わりに、リスト内のすべての情報を取得してから、アプリケーションで不要なものを除外します。

したがって、基本的には、最後の可能な月まで待ってから自分自身をコミットすることになります。

88
Jonathan Allen

IQueryable<T>を返すことには、結果の列挙を実際に開始し、クエリを他のクエリと組み合わせてサーバー側で実行できるまで実行が遅延するという利点があります。

問題は、このメソッドではデータベースコンテキストのライフタイムを制御できないことです。オープンコンテキストが必要であり、クエリが実行されるまで開いたままにしておく必要があります。そして、コンテキストが破棄されることを確認する必要があります。結果をList<T>T[]、または同様のものとして返す場合、合成クエリの実行の遅延とサーバー側の実行を失いますが、データベースコンテキストの有効期間を制御できます。

もちろん、最適なものは実際の要件によって異なります。それは単一の真実のない別の質問です。

23

AsQueryableIEnumerable<T>の拡張メソッドで、次の2つのことを実行できます。

  • IEnumerable<T>IQueryable<T>だけでキャストを実装し、何もしない場合。
  • それ以外の場合は、ラムダをコンパイルしてEnumerable拡張メソッドを呼び出すすべてのメソッドを実装する「偽」IEnumerable<T>EnumerableQuery<T>)を作成します。

そのため、AsQueryableを使用するほとんどの場合、uがIQueryableをメソッドに渡すことを強制され、代わりにIEnumerableがなければ、ハックです。

注:AsQueryableはハックですが、もちろんIQueryableはそうではありません!

11
Olmo

IQueryable<T>を返すと、結果が実際に使用されるまでクエリの実行が延期されます。それまでは、IQueryable<T>に対して追加のデータベースクエリ操作を実行することもできます。 Listでは、一般的にメモリ内の非効率的な操作に制限されます。

4
dahlbyk