2012-03-19 68 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()); 
相關問題