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のサイズに上限はありますか?