Linq到SQL组合两个表达式<;Func<;T、 bool>>;(“where clause”)带有和
本文关键字:lt gt bool where clause Func 组合 两个 表达式 SQL Linq | 更新日期: 2023-09-27 18:25:25
首先,我必须说,我在StackOverflow上读过几篇关于这方面的文章,但我无法获得所需的结果。
让我解释一下上下文(简化):我使用Linq to SQL来查询最近访问过该商店的客户,并(可选)只获取那些支付了一定金额的客户。假设我有一个包含客户、访问和支付类的模型。
因此,专注于Where
表达式,我尝试这样做:
Expression<Func<Entityes.Clients, bool>> filter = null;
filter = c =>
c.Visits.Any(v => v.VisitDate > DateTime.Now.Date.AddMonths(-(int)visitsSince));
if (minPayment.HasValue && minPayment.Value > 0)
{
filter.And(
c => c.Payments.Sum(p => p.Quantity) > minPayment.Value);
}
filter.And
方法是一种扩展方法,在这个论坛上推荐,下面你可以看到定义:
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1,
Expression<Func<T, bool>> expression2)
{
InvocationExpression invokedExpression =
Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
}
然而,这对我来说并不像预期的那样有效,结果也没有按付款金额进行过滤。数据或linq-to-sql模型没有错误,因为这段代码运行良好:
filter = c =>
c.Visits.Any(v => v.VisitDate > DateTime.Now.Date.AddMonths(-(int)visitsSince)))
&& c => c.Payments.Sum(p => p.Quantity) > minPayment.Value;
然而,我不想使用最后一段代码,因为我有一些更复杂的场景,在这些场景中,我需要使用每个部分的"和/或"组合来逐步构建过滤器表达式。
PD:我是一个"ADO.Net数据集"的人,试图学习Linq到SQL以及很快的实体框架,我希望很快对StackOverflow社区有用。
您没有将And
ing的结果分配给任何对象。
我想你代码的各个部分应该读如下:
if (minPayment.HasValue && minPayment.Value > 0)
{
filter = filter.And(
c => c.Payments.Sum(p => p.Quantity) > minPayment.Value);
}
问题是,您的(或您提到的SO)And
函数返回包含两个表达式的联合的表达式。它不会改变调用它的对象。
问题是这一行:
filter.And(c => c.Payments.Sum(p => p.Quantity) > minPayment.Value);
And
方法返回另一个未分配给任何对象的委托。试试这个:
filter = filter.And(c => c.Payments.Sum(p => p.Quantity) > minPayment.Value);
澄清一下,And
是一种采用两个表达式并结合它们的逻辑来创建新表达式的方法。它不会更改对其执行的表达式,而是将新表达式作为返回值返回。因此,在您的代码中,您调用filter.And(...)
,但不对返回值执行任何操作,因此filter
仍然引用原始lambda表达式。
查看LinqKit及其PredicateBuilder类:http://www.albahari.com/nutshell/predicatebuilder.aspx