簡體   English   中英

我怎樣才能使用謂詞 <T> 在EF Where()子句中?

[英]How can I use a Predicate<T> in an EF Where() clause?

我正在嘗試在我的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.

我不能使用第一個選項,因為這是一個簡單的例子,實際上,我正在嘗試將一堆謂詞組合在一起(使用和不使用等)以實現我想要的功能。

如何讓EF Linq提供程序“理解”我的謂詞?

如果我使用Func<T, bool>我會得到相同的結果。 它適用於Expression<Func<T>> ,但我無法將表達式組合在一起進行復雜過濾。 如果可能的話,我寧願避免使用外部庫。

更新:
如果無法做到這一點,我有什么選擇? 也許以某種方式組合/或/和表達表達式以達到同樣的效果?

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>x => x.HasMoney作為表達式樹,而不是將其編譯為.NET方法
  • 使用Expression<Func<Customer, bool>>而不是Expression<Predicate<Customer>> ,因為這就是Queryable.Where期望的
  • 直接傳遞它。在.Where ,使用多個.Where調用而不是&&組合它們。

這是可能得到更復雜的條件(包括沒有,或者等)通過改寫他們的合作.Union.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));

不幸的是,沒有辦法在EF linq中使用Predicate<T> ,因為它無法在SQL查詢上映射它。 這可以僅使用表達式來完成,因為它們可以被解析並轉換為SQL。

事實上,有4種語言功能使linq成為可能:

  1. 擴展方法
  2. 類型推斷
  3. 關閉
    特別是linq2sql
  4. 表達式

更新:
可能的解決方案是以編程方式構建表達式 如何:使用表達式樹構建動態查詢

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM