[英]Linq-to-SQL combining two Expression<Func<T, bool>> (“where clause”) with and/or
First, I must say that I have read several post about this at StackOverflow but I cannot get the desired result. 首先,我必须说我已经在StackOverflow上阅读了几篇有关此内容的帖子,但我无法获得所需的结果。
Let me explain the context (simplified): I'm using Linq-to-SQL to query customers with recent visits to the store and (optionally) get only those with certain amount of payments. 让我解释上下文(简化):我使用Linq-to-SQL来查询最近访问商店的客户,并(可选)只获得具有一定金额的付款。 Suppose I have a model with client, visits and payments classes.
假设我有一个客户端,访问和付款类的模型。
So, focusing on the Where
expression, I'm trying this: 所以,专注于
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);
}
The filter.And
method is an extension method, recommended at this forum, below you can see the definition: 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);
}
However, this doesn't work for me as expected and results are not filtered by payment amount. 但是,这对我不起作用,并且结果不会按付款金额进行过滤。 There is no error with data or linq-to-sql model because this code works fine:
数据或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;
However, I don't want to use the last code because I have some more complex scenarios in which I need to build the filter expression step-by-step with an 'and/or' combination of each part. 但是,我不想使用最后一个代码,因为我有一些更复杂的场景,我需要使用每个部分的'和/或'组合逐步构建过滤器表达式。
PD: I'm a "ADO.Net DataSets" guy trying to learn Linq-to-SQL and soon Entity Framework, I hope to be useful to the StackOverflow community soon. PD:我是一个试图学习Linq-to-SQL和很快实体框架的“ADO.Net DataSets”,我希望很快对StackOverflow社区有用。
You are not assigning the result of And
ing to anything. 你是不是分配的结果,
And
荷兰国际集团任何东西。
I suppose the respective part of your code should read as following: 我想您的代码的相应部分应如下所示:
if (minPayment.HasValue && minPayment.Value > 0)
{
filter = filter.And(
c => c.Payments.Sum(p => p.Quantity) > minPayment.Value);
}
The thing is that your (or SO's as you mentioned) And
function returns the expression containing the conjunction of two expression. 问题是你的(或你提到的SO)
And
函数返回包含两个表达式的连接的表达式。 It does not alter the object it is invoked on. 它不会改变它被调用的对象。
The problem is this line: 问题是这一行:
filter.And(c => c.Payments.Sum(p => p.Quantity) > minPayment.Value);
The And
method returns another delegate which you haven't assigned to anything. And
方法返回另一个您没有分配给任何东西的委托。 Try this: 尝试这个:
filter = filter.And(c => c.Payments.Sum(p => p.Quantity) > minPayment.Value);
Just to clarify, And
is a method which takes two expressions and combines their logic to create a new expression. 只是为了澄清,
And
是一种方法,它采用两个表达式并结合它们的逻辑来创建一个新的表达式。 It doesn't change the expression it's executed on, but returns the new expression as a return value. 它不会更改它执行的表达式,但会返回新表达式作为返回值。 So in your code you're calling
filter.And(...)
but not doing anything with the return value, so filter
still references the original lambda expression. 所以在你的代码中你调用
filter.And(...)
但没有对返回值做任何事情,所以filter
仍然引用原始的lambda表达式。
查看LinqKit和它的PredicateBuilder类: http : //www.albahari.com/nutshell/predicatebuilder.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.