我正在使用一些代码(可用here https://web.archive.org/web/20160221084142/http://blogs.msdn.com:80/b/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-using-linq-to-entities.aspxMSDN 上)动态构建包含多个 OR“子句”的 LINQ 表达式。
相关代码是
var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));
这会生成一个如下所示的 LINQ 表达式:
(((((ID = 5) OR (ID = 4)) OR (ID = 3)) OR (ID = 2)) OR (ID = 1))
使用此表达式时,我遇到了递归限制 (100),因此我想生成一个如下所示的表达式:
(ID = 5) OR (ID = 4) OR (ID = 3) OR (ID = 2) OR (ID = 1)
我如何修改表达式构建代码来做到这一点?
您需要修改生成,以便它构建平衡树而不是序列OR
s,其中左子树是单个表达式,右子树包含所有剩余元素。以图形方式:
Your code Better
--------- --------
OR OR
#1 OR OR OR
#2 OR #1 #2 #3 #4
#3 #4
正如您所看到的,即使在这种简单的情况下,更好的方法也不是那么深(递归嵌套)。生成更好的表达式树的代码可以用 C# 编写为递归方法:
Expression GenerateTree(List<Expression> exprs, int start, int end) {
// End of the recursive processing - return single element
if (start == end) return exprs[start];
// Split the list between two parts of (roughly the same size)
var mid = start + (end - start)/2;
// Process the two parts recursively and join them using OR
var left = GenerateTree(exprs, start, mid);
var right = GenerateTree(exprs, mid+1, end);
return Expression.Or(left, right);
}
// Then call it like this:
var equalsList = equals.ToList();
var body = GenerateTree(equalsList, 0, equalsList.Length);
我没有尝试代码,所以可能会有一些小错误,但它应该显示出这个想法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)