2

我正在使用 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 的大小是否有上限?

4

1 回答 1

1

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

于 2013-05-06T07:24:40.260 回答