好的,这就是我正在创建动态表达式来对数据库执行的问题,这很好。当我使用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
每个要添加的表达式都有不同的参数。
我出错的任何想法?
由于
答案 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);
}