【问题标题】:Expression.Lambda: Variable 'x' of type '' referenced from scope '', but it is not definedExpression.Lambda:从范围“”引用的“”类型的变量“x”,但未定义
【发布时间】:2012-03-19 22:13:34
【问题描述】:

我看到已连接 topic 但是...

我试图实现规范模式。如果我使用 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());

谢谢@Jon Skeet

【问题讨论】:

    标签: c# lambda


    【解决方案1】:

    每个实体都有一组单独的参数,因此仅使用 secondCondition.Parameters 不会给 firstCondition.Body 一个参数。

    幸运的是,您根本不需要自己编写所有这些内容。只需使用 Joe Albahari 的 PredicateBuilder - 一切都为您完成。

    【讨论】:

      【解决方案2】:

      如果您有兴趣,这是您必须使用的表达式树:

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

      【讨论】:

        猜你喜欢
        • 2015-10-08
        • 2011-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-10
        • 1970-01-01
        相关资源
        最近更新 更多