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

本文关键字:参数 表达式 Lambda Expression 组合 | 更新日期: 2023-09-27 18:02:03

好的,所以这里的问题是我创建一个表达式动态执行对数据库,这工作得很好。当我使用expression添加另一个表达式时,问题出现了。此外,表达式组合得很好,但参数不起作用,我的代码如下:

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

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

你知道我哪里错了吗?

谢谢

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

如何在使用Expression组合表达式时使用多个参数。λ

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

Expression<Func<Invoice, bool>> condition

表示Invoice类型的单个参数。

要解决此问题,请替换

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

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

,在代码的其余部分,将param[i]替换为param

注:实际上不需要为每个过滤器创建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);
}