2012-03-19 66 views
4

只见连接topic但是......Expression.Lambda:变量“X”型“”引用的范围',但它没有定义

我试图实现规范模式。如果我与System.Linq.Expressions API创建OR或AND表达明确,我会得到错误的范围引用

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 

EDITED

我想在我的工作代码,它看起来像使用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 => 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()); 

谢谢@乔恩飞碟双向

回答

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()); 
相关问题