13

EFフィルタリングコードで述語を使用しようとしています。

これは機能します:

IQueryable<Customer> filtered = customers.Where(x => x.HasMoney && x.WantsProduct);

でも、これ:

Predicate<T> hasMoney = x => x.HasMoney;
Predicate<T> wantsProduct = x => x.WantsProduct;
IQueryable<Customer> filtered = customers.Where(x => hasMoney(x) && wantsProduct(x));

実行時に失敗します:

The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.

これは単純な例であるため、最初のオプションを使用することはできません。実際には、一連の述語を組み合わせて(and、not、orなど)、目的を達成しようとしています。

EF Linqプロバイダーに述語を「理解」させるにはどうすればよいですか?

を使用しても同じ結果が得られますFunc<T, bool>。で動作しますExpression<Func<T>>が、式を組み合わせて複雑なフィルタリングを行うことはできません。可能であれば、外部ライブラリは避けたいと思います。

更新:
これができない場合、どのようなオプションがありますか?おそらく、同じ効果を達成するために、式を何らかの方法で組み合わせたり、「ed」したり、「ed」したりしますか?

4

2 に答える 2

12
Expression<Func<Customer, bool>> hasMoney = x => x.HasMoney;
Expression<Func<Customer, bool>> wantsProduct = x => x.WantsProduct;
IQueryable<Customer> filtered = customers.Where(hasMoney).Where(wantsProduct);
  • 式ツリーとしてExpression<T>残すために使用し、.NETメソッドにコンパイルしないために使用しますx => x.HasMoney
  • ではExpression<Func<Customer, bool>>なく使用Expression<Predicate<Customer>>してください。Queryable.Where
  • の代わりに複数の呼び出し.Whereを使用してそれらを組み合わせて、直接に渡します。.Where&&

.Union、などを使用してそれらを書き換えることにより、より複雑な条件(not、またはなどを含む)を機能させることができます.Except

別の方法は、 LINQKitAsExpandable:を使用することです。

Expression<Func<Customer, bool>> hasMoney = x => x.HasMoney;
Expression<Func<Customer, bool>> wantsProduct = x => x.WantsProduct;
IQueryable<Customer> filtered = customers.AsExpandable().Where(x => hasMoney.Invoke(x) && wantsProduct.Invoke(x));
于 2012-11-15T08:51:43.027 に答える
4

残念ながらPredicate<T>、EF linqをSQLクエリにマッピングすることは不可能であるため、EFlinqで使用する方法はありません。これは、式を解析してSQLに変換できるため、式でのみ実行できます。

実際、linqを可能にした4つの言語機能があります。

  1. 拡張メソッド
  2. 型推論
  3. クロージャ
    と特にlinq2sqlの場合

更新:
考えられる解決策は、プログラムで式を作成することです。方法:式ツリーを使用して動的クエリを作成する

于 2012-11-15T01:20:56.617 に答える