Expression.Lambda: переменная 'x' типа '' ссылка из области видимости '', но она не определена - PullRequest
4 голосов
/ 20 марта 2012

Я видел подключенную тему , но ...

Я пытался реализовать шаблон спецификации.Если я явно создаю выражение «И» или «И» с помощью API System.Linq.Expressions, я получу ошибку

Переменная 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

Я пытался использовать шаблон спецификации с 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 ]

7 голосов
/ 20 марта 2012

Каждое из этих тел имеет отдельный набор параметров, поэтому использование secondCondition.Parameters не дает firstCondition.Body параметра.

К счастью, вам не нужно писать все это самостоятельно ввсе.Просто используйте PredicateBuilder Джо Албахари - все для вас.

4 голосов
/ 20 марта 2012

Если вам интересно, это дерево выражений, которое вы должны использовать:

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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...