具有大表达式树的EF查询中的StackOverflowException

时间:2013-02-18 18:54:05

标签: entity-framework linq-to-entities entity-framework-5

我正在使用EF 5来执行需要多个Where条件的选择。

其中一个条件是仅包含Code字段位于UI提供的代码列表中的记录(例如SQL翻译:{{1​​}})。

为实现这一目标,我构建了一个基于this post的表达式树,代码为:

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); 大小合理时,这非常有效。但是,当列表包含超过1000个代码时,我会在desiredCodes迭代器被评估的时刻得到StackOverflowException

问题

是否有其他方法可以实现不易受StackOverflowException攻击的 Contains 要求?

SQL(SQL Server 2012)生成的SQL大小是否有上限?

1 个答案:

答案 0 :(得分:0)

我们遇到了同样的问题,在我分析了bug之后,到目前为止唯一的解决方法是手动编写查询(例如,通过string.Join()或其他东西生成IN(...),因为EF似乎通过递归遍历表达式来构建语句。