Expression.Lambda: variable 'x' of type '' referencing scope '' but not defined

I saw a related topic , but ...

I tried to implement a specification template. If I create Or or Ex Expression explicitly using the System.Linq.Expressions API, I will get an error

InvalidOperationExpression variable 'x' referring to scope.

For example, this is my code

 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

I tried using the specification template with Linq to Nhibernate , so in my working code it looks like this:

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

So, I want to use code like this x => x.Id> 4.

Edited

So my decision

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

Thanks @Jon Skeet

+4
source share
2 answers

Each of these bodies has a separate set of parameters, so using only secondCondition.Parameters does not give the firstCondition.Body parameter.

Fortunately, you don’t have to write all this yourself. Just use Joe Albahari's PredicateBuilder - all made for you.

+7
source

If you're interested, this is an expression tree that you should use:

 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()); 
+4
source

All Articles