我正在尝试在我的 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/and'以达到相同的效果?
最佳答案
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
重写更复杂的条件(包括 not 或 or 等)是可能的。 , .Except
等
另一种方法是使用 LINQKit的 AsExpandable
:
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));
关于c# - 如何在 EF Where() 子句中使用 Predicate<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13390126/