使用Expression.Lambda组合表达式时如何使用多个参数

时间:2016-08-12 10:40:41

标签: c# entity-framework lambda expression

好的,这就是我正在创建动态表达式来对数据库执行的问题,这很好。当我使用Expression.AndAlso添加另一个表达式时出现问题,表达式组合良好,但参数不起作用,我的代码在下面。

Expression<Func<Invoice, bool>> condition = null;

ParameterExpression[] param = new ParameterExpression[sessionModel.FilterChildren.Count];

foreach (var filter in sessionModel.FilterChildren) {

   param[i] = Expression.Parameter(typeof(Invoice), filter.SysName);

   Type type = Type.GetType(filter.Type);

   if (i == 0)
     condition =
         Expression.Lambda<Func<Invoice, bool>>(
             Expression.Equal(
             Expression.Property(param[i], filter.SysName),
             Expression.Constant(filter.Value, type)
            ),
              param[i]);
    else {
      var newCond = Expression.Lambda<Func<Invoice, bool>>(
         Expression.Equal(
             Expression.Property(param[i], filter.SysName),
             Expression.Constant(filter.Value, type)
            ),
              param[i]);

       var test = Expression.AndAlso(condition.Body, newCond.Body);

       condition = Expression.Lambda<Func<Invoice, bool>>(test, param);
    }
    i++;
  }

它会抛出错误

Incorrect number of parameters supplied for lambda declaration

每个要添加的表达式都有不同的参数。

我出错的任何想法?

由于

1 个答案:

答案 0 :(得分:3)

  

使用Expression.Lambda

组合表达式时如何使用多个参数

您不应该使用多个参数。 lambda表达式

Expression<Func<Invoice, bool>> condition

表示Invoice类型的单个参数。

要解决此问题,请替换

ParameterExpression[] param = new ParameterExpression[sessionModel.FilterChildren.Count];

var param = Expression.Parameter(typeof(Invoice), "invoice");

并在其余代码中,将param[i]替换为param

P.S。没有必要为每个过滤器创建lambda表达式,因为正如您所看到的,在组合它们时,您只使用Body。整个过程可以简化为:

Expression<Func<Invoice, bool>> condition = null;
if (sessionModel.FilterChildren.Any())
{
    var parameter = Expression.Parameter(typeof(Invoice), "invoice");
    var body = sessionModel.FilterChildren
        .Select(filter => Expression.Equal(
            Expression.Property(parameter, filter.SysName),
            Expression.Constant(filter.Value, Type.GetType(filter.Type))))
        .Aggregate(Expression.AndAlso);
    condition = Expression.Lambda<Func<Invoice, bool>>(body, parameter);
}