我正在使用 EF 5 执行需要多种Where
条件的选择。
其中一个条件是仅包含Code
字段位于 UI 提供的代码列表中的记录(例如 SQL 翻译:)AND Code IN (123, 456)
。
为此,我根据这篇文章构建了一个表达式树,代码如下:
static public Expression<Func<TElement, bool>>
BuildContainsExpression<TElement, TValue>(
Expression<Func<TElement, TValue>> valueSelector,
IEnumerable<TValue> values)
{
if (null == valueSelector)
{
throw new ArgumentNullException("valueSelector");
}
if (null == values) { throw new ArgumentNullException("values"); }
ParameterExpression p = valueSelector.Parameters.Single();
if (!values.Any())
{
return e => false;
}
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));
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
该代码的使用如下:
// List<long> desiredCodes is provided by the UI
containsExpression = LinqToEntitiesUtil.BuildContainsExpression<MyClass, long>
(my => my.Code, desiredCodes);
// In the actual code there are several other Where conditions as well
var matching = ctx.MyClasses.Where(containsExpression).Select(my => my);
当desiredCodes
尺寸合理时,这非常有效。但是,当列表包含超过 1000 个代码时,我会在迭代器被评估StackOverflowException
的那一刻得到。matching
问题
是否有另一种方法来实现不受 StackOverflowException 影响的包含要求?
SQL (SQL Server 2012) 对生成的 SQL 的大小是否有上限?