我看到了联系topic但是......
我试图实现规范模式。如果我使用System.Linq.Expressions
API明确创建Or或And Expression,我将收到错误
从范围引用的InvalidOperationExpression变量'x'。
例如,这是我的代码
public class Employee
{
public int Id { get; set; }
}
Expression<Func<Employee, bool>> firstCondition = x => x.Id.Equals(2);
Expression<Func<Employee, bool>> secondCondition = x => x.Id > 4;
Expression predicateBody = Expression.OrElse(firstCondition.Body, secondCondition.Body);
Expression<Func<Employee, bool>> expr =
Expression.Lambda<Func<Employee, bool>>(predicateBody, secondCondition.Parameters);
Console.WriteLine(session.Where(expr).Count()); - //I got error here
已编辑
我尝试使用Specification pattern with Linq to Nhibernate,因此在我的工作代码中看起来像是:
ISpecification<Employee> specification = new AnonymousSpecification<Employee>(x => x.Id.Equals(2)).Or(new AnonymousSpecification<Employee>(x => x.Id > 4));
var results = session.Where(specification.is_satisfied_by());
所以我想使用像这样的代码x =&gt; x.Id&gt; 4.
被修改
所以我的解决方案是
InvocationExpression invokedExpr = Expression.Invoke(secondCondition, firstCondition.Parameters);
var expr = Expression.Lambda<Func<Employee, bool>>(Expression.OrElse(firstCondition.Body, invokedExpr), firstCondition.Parameters);
Console.WriteLine(session.Where(expr).Count());
谢谢@Jon Skeet
答案 0 :(得分:7)
每个主体都有一组单独的参数,因此仅使用secondCondition.Parameters
不会给firstCondition.Body
一个参数。
幸运的是,您根本不需要自己编写所有这些内容。只需使用Joe Albahari的PredicateBuilder
- 这一切都是为你完成的。
答案 1 :(得分:4)
如果您感兴趣,这是您必须使用的表达式树:
var param = Expression.Parameter(typeof(Employee), "x");
var firstCondition = Expression.Lambda<Func<Employee, bool>>(
Expression.Equal(
Expression.Property(param, "Id"),
Expression.Constant(2)
),
param
);
var secondCondition = Expression.Lambda<Func<Employee, bool>>(
Expression.GreaterThan(
Expression.Property(param, "Id"),
Expression.Constant(4)
),
param
);
var predicateBody = Expression.OrElse(firstCondition.Body, secondCondition.Body);
var expr = Expression.Lambda<Func<Employee, bool>>(predicateBody, param);
Console.WriteLine(session.Where(expr).Count());