私はIQueryable<T>
の式を定義し、その定義をカプセル化して保存して再利用したり、後で大きなクエリに埋め込んだりしたいとします。例:LINQの遅延実行を維持する方法は?
IQueryable<Foo> myQuery =
from foo in blah.Foos
where foo.Bar == bar
select foo;
ここで、myQueryオブジェクトをそのまま使用して、説明したように使用できます。それをパラメータ化する
最善の方法:しかし、いくつかのものは私はわからないんだけど?最初にメソッドでこれを定義し、メソッドの結果として
IQueryable<T>
を返しました。この方法では、メソッドの引数としてblah
とbar
を定義することができ、毎回新しいIQueryable<T>
を作成すると思います。これはIQueryable<T>
のロジックをカプセル化する最良の方法ですか?他の方法はありますか?クエリが
IQueryable
ではなくスカラに変換されるとどうなりますか?たとえば、このクエリを正確に表示するには、.Any()
を追加して、一致する結果があるかどうかを教えてください。(...).Any()
を追加すると、結果はbool
となり、直ちに実行されます。これらのQueryable
演算子(Any
、SindleOrDefault
など)をすぐに実行することなく利用する方法はありますか? LINQ-to-SQLはこれをどのように処理しますか?
編集:パート2はIQueryable<T>.Where(Expression<Func<T, bool>>)
対IQueryable<T>.Any(Expression<Func<T, bool>>)
間の制限の違いが何であるかを理解しようとについて本当に多くのです。後者は、実行が遅れる大きなクエリを作成するときに柔軟性がないように見えます。 Where()
を追加して、後で他の構造を追加してから最後に実行することができます。 Any()
はスカラー値を返すので、クエリの残りの部分が構築される前にすぐに実行されるように聞こえます。
#1のように、新しいIQueryableを基本的に構築する方法は、たぶん*良いことです*ので、私は廃棄の問題に遭遇しません。 #2では、LINQ-to-SQLが「Any」演算子をどのように変換できるのか混乱していますが、延期することはできません。より大きなクエリの中で 'Any'演算子を使用するのであれば、すぐにそこで実行されるのでしょうか、それともより大きなクエリの実行の一部ですか? – mckamey
OK私はほとんどそこにいると思う。 '.Any()'を 'where'節に埋め込むと、それはループ内で実行されませんでしたか?適切なSQL式にコンパイルし、それを送信します。したがって実際には、どのように使用されているかのように、遅延実行を防ぐ '.Any()'ではありません。基本的には、*全体*クエリの結果がスカラーの場合、コンパイラは 'IQueryable'を構築するのではなく、今結果を必要としていると判断します。 –
mckamey
@McKAMEYは正しいです。延期できないコンテキストで.Any()を使用すると、すぐに実行されます。 .Where()の場合、それは延期可能な式を探しているので、大丈夫です。 varまたはforeachループの場合は、遅延が発生しないため実行されます。 – Joseph