2

EF 5を使用して、多数のWhere条件を必要とする選択を実行しています。

Codeそれらの条件の1つは、フィールドが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に対して脆弱ではないContains要件を実装する別の方法はありますか?

SQL(SQL Server 2012)によって課される生成されたSQLのサイズに上限はありますか?

4

1 に答える 1

1

同じ問題が発生しました。バグを分析した後、現在のところ唯一の回避策は、クエリを手動で記述することです (たとえば、string.Join() などで IN (...) を生成する)。式 3 を再帰的にたどってステートメントを作成します。

于 2013-05-06T07:24:40.260 に答える