2012-03-19 12 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 

である私は私の仕事のコードでは、それがどのように見える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()); 

はそう firstCondition.Bodyにパラメータを与えるものではありませんだけで secondCondition.Parametersを使用して、あなたにそれらの体の各パラメータの別のセットを持っている@ジョンスキート

答えて

7

に感謝です。

幸運なことに、このすべてを自分で書く必要はありません。 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()); 
関連する問題