使用递归创建 (Lambda) 表达式
Creating an (Lambda) Expression using recursion
我有以下词典:
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 属性)用于指定二进制等式表达式中的常量。
e
属于 Entity
类型,保证具有此属性。
结果表达式的类型应为 Expression<Func<Entity, bool>>
如何使用递归构建此表达式?
我说递归是因为它听起来像是一种自然的解决方案,但迭代的解决方案将是首选。
我尝试了迭代替代方案,但最终得到了一个丑陋且不太容易理解的代码。
但是,我无法为这个问题创建递归方法。
将单个表达式的创建留给您,只需在迭代循环中将它们组合在一起即可:
// 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);
我有以下词典:
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 属性)用于指定二进制等式表达式中的常量。
e
属于 Entity
类型,保证具有此属性。
结果表达式的类型应为 Expression<Func<Entity, bool>>
如何使用递归构建此表达式?
我说递归是因为它听起来像是一种自然的解决方案,但迭代的解决方案将是首选。
我尝试了迭代替代方案,但最终得到了一个丑陋且不太容易理解的代码。
但是,我无法为这个问题创建递归方法。
将单个表达式的创建留给您,只需在迭代循环中将它们组合在一起即可:
// 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);