使用递归创建(Lambda)表达式

本文关键字:Lambda 表达式 创建 递归 | 更新日期: 2023-09-27 18:02:09

我有以下字典:

Dictionary<string, PropertyInfo> filterProperties;

这本字典的内容可以是这样的:

- "Language": [QueryData.Lang],
- "Id": [Querydata.UserId]

每个字符串键映射到一个my QueryData类型的属性。

现在假设我有以下QueryData实例:

QueryData: { Lang= "en", UserId = "mcicero" }
以前面的字典为例,我想构建以下表达式:
e => e.Language == "en" && e.Id == "mcicero";

如你所见,字典键用于访问e的属性,字典值(QueryData属性)用于指定二进制相等表达式中的常量。

eEntity类型,并且保证具有这些属性。

结果表达式的类型应为Expression<Func<Entity, bool>>

如何使用递归构建这个表达式?

我说递归是因为它听起来像一个自然的解决方案,但迭代的解决方案更可取。

我尝试了迭代替代方案,最终得到了一个丑陋且不太容易理解的代码。

但是,我在为这个问题创建递归方法时遇到了麻烦。

使用递归创建(Lambda)表达式

将单个表达式的创建留给您,只需在迭代循环中将它们组合在一起:

// For an IEnumerable<Expression> in "expressions"
Expression left = null;
foreach(var right in expressions)
{
  if(left == null)
    left = right;
  else
    left = Expression.And(left, right);
}
// Combined expression is in "left"
// Don't forget it will be null if there were no expressions provided...

或者在一行中使用LINQ:

var expr = expressions.Aggregate(Expression.And);

对于感兴趣的人,在一行中:

Expression expr = filterProperties.Select(i => Expression.Equal(
                                                  Expression.Property(entityParameter, i.Key),
                                                  Expression.Constant(i.Value.GetValue(queryObj))
                                         )).Aggregate(Expression.And);