linqクエリの範囲変数をパラメーターとして使用しようとしています。
のような簡単なもの;
private static Expression<Func<context.Table1, bool>> funstuff(context.Table2 data)
{
return x => true;
}
別の簡単な例のように、クロス結合を使用します。
var fun = from table2 in context.Table2
from table1 in context.Table1.Where(funstuff(table2))
select table1;
var f = fun.ToList();
そして、私はこのエラーが発生しています。
タイプ 'context.Table2'の変数 'table2'がスコープ ''から参照されていますが、定義されていません
エンティティフレームワーク6でパラメータとして範囲変数を使用することは可能ですか?
編集
コンテキストはエンティティフレームワークのdbcontextです
この正確なコードは機能します。
var fun = from table2 in context.Table2
from table1 in context.Table1.Where(x => table2.Id == 1)
select table1;
var f = fun.ToList();
これは機能しません。
private static Expression<Func<context.Table1, bool>> funstuff(context.Table2 data)
{
return x => data.Id == 1;
}
var fun = from table2 in context.Table2
from table1 in context.Table1.Where(funstuff(table2))
select table1;
var f = fun.ToList();
私はそれがうまくいくと思っていました。
私はあなたcontext
がであると思いますDbContext
。
ほとんどの関数は似ていますが、との間には違いがQueryable
ありEnumerable
ます。
IEnumerableオブジェクトには、ローカルメモリにあるコレクション内のオブジェクトを列挙するためのすべてのコードが含まれています。IEnumerableオブジェクトは、ローカル関数を列挙しながら使用できます。
クエリ可能な列挙は、他のプロセッサで実行されることを意図しています。IQueryableオブジェクトには、他のプロセッサが理解できる形式に変換できる式が含まれています。
この翻訳は、Expression
ではなく、IQueryable
:の別のプロパティにありますProvider
。Provider
どのタイプのマシン上で知ってExpression
実行されます。要求に応じて、Provider
はこの式をこのマシンが理解できる形式に翻訳(コンパイル)し、翻訳をこのマシンに送信します。
オブジェクトはをcontext.Table2
実装しIQueryable
ます。のプロバイダーは、IQueryable
クエリをSQLに変換する方法を知っています。SQLはfunstuff
、のような個人的な関数をProvider
知らないため、SQLに変換する方法を知りません。実際、DbSetはすべての種類のLINQメソッドをサポートしているわけではありません。
MSDN:サポートされているおよびサポートされていないLINQメソッド(LINQ to Entities)を参照してください。
したがって、ステートメントがIQuery可能である限り、ローカル関数を呼び出すことはできません。
ローカル関数を呼び出すことが本当に重要な場合は、として実行できますIEnumerable
。これは、関数AsEnumerableを使用して行います。これにより、の入力データがAsEnumerable
ローカルメモリに送られます。その後、クエリがであるかのようにすべてのローカル関数を呼び出すことができますIEnumerable
ただし、パフォーマンス上のリスクがあります。入力が数千のオブジェクトであり、最終的に少数のオブジェクトしか得られない場合、このすべての情報をローカルメモリに取り込むのは無駄です。
結論:を呼び出す前に、ローカルメモリに転送されるデータを最終結果で必要となるサイズに制限するようにしてくださいAsEnumerable
。その後、必要なローカル関数を呼び出すことができます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加