【问题标题】:Creating an (Lambda) Expression using recursion使用递归创建 (Lambda) 表达式
【发布时间】:2015-07-10 13:02:28
【问题描述】:

我有以下字典:

Dictionary<string, PropertyInfo> filterProperties;

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

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

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

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

QueryData: { Lang= "en", UserId = "mcicero" }

以前面的字典为例,我想构建以下表达式:

e => e.Language == "en" && e.Id == "mcicero";

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

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

结果表达式的类型应该是Expression&lt;Func&lt;Entity, bool&gt;&gt;

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

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

我尝试了迭代替代方案,结果得到了一个丑陋且难以理解的代码。

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

【问题讨论】:

  • 您可能想使用动态 linq。这是一些信息weblogs.asp.net/scottgu/…
  • 您可能需要查看Expression Trees
  • 忽略所有字典和 QueryData 内容,您只想知道如何在运行时从 PropertyInfo 和字符串创建像 e =&gt; e.Language = "en" 这样的表达式。
  • 你能更好地解释一下,构建这个表达式是什么意思吗?
  • @StefanSteinegger 实际上,我知道如何创建这样的表达式,但我不知道如何将每个映射表达式与 AND (&&) 表达式连接起来。字典大小可以是可变的

标签: c# recursion lambda expression expression-trees


【解决方案1】:

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

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

【讨论】:

  • 感谢您提供的一行 LINQ 语句!漂亮!
  • 这个&ing会产生尽可能深的树,当有很多节点时会降低性能。您应该尝试构建一个尽可能平坦的树,例如将它们放入队列中,取出前 2 个元素,然后将它们 &ing 并放在最后,直到只剩下 1 个节点。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 2011-07-23
    相关资源
    最近更新 更多