Expression.Lambda: переменная 'x' типа '' ссылка из области видимости '', но она не определена
Я видел связанную тему, но...
Я пытался реализовать шаблон спецификации. Если я создаю выражение Or или And явно с System.Linq.Expressions
API, я получу ошибку
Переменная 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
РЕДАКТИРОВАНИЕ
Я попытался использовать шаблон спецификации с Linq для 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());
Спасибо @ Джон Скит
2 ответа
Каждое из этих тел имеет отдельный набор параметров, поэтому, используя только secondCondition.Parameters
не дает firstCondition.Body
параметр.
К счастью, вам не нужно писать все это самостоятельно. Просто используйте PredicateBuilder
Джо Албахари - все сделано для вас.
Если вам интересно, это дерево выражений, которое вы должны использовать:
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());