Expression.Lambda: 变量'x'的类型为'',被范围''引用,但并未定义。

6
我看到了一个相关的链接topic,但是...
我正在尝试实现规范模式。如果我使用System.Linq.Expressions API显式地创建Or或And表达式,我会收到错误消息

InvalidOperationExpression variable 'x' referenced from scope.

例如,这是我的代码:
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

我尝试使用Linq to Nhibernate 中的规范模式,在我的工作代码中它看起来像:

EDITED

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 => x.Id > 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。
2个回答

7

每个参数体都有自己的一组参数,所以仅使用 secondCondition.Parameters 不能给 firstCondition.Body 提供参数。

幸运的是,你根本不需要自己编写所有这些内容。只需使用 Joe Albahari 的 PredicateBuilder - 它已为您完成了所有操作。


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());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接