Skip to content

Commit d723553

Browse files
authored
[release/10.0] Fix parameter limit (because of sp_executesql). (#37334)
1 parent e6eef43 commit d723553

File tree

2 files changed

+38
-12
lines changed

2 files changed

+38
-12
lines changed

src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal;
1616
/// </summary>
1717
public class SqlServerSqlNullabilityProcessor : SqlNullabilityProcessor
1818
{
19-
private const int MaxParameterCount = 2100;
19+
private int MaxParameterCount => UseOldBehavior37336 ? 2100 : 2100 - 2;
2020

2121
private static readonly bool UseOldBehavior37151 =
2222
AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue37151", out var enabled) && enabled;
2323

2424
private static readonly bool UseOldBehavior37185 =
2525
AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue37185", out var enabled) && enabled;
2626

27+
private static readonly bool UseOldBehavior37336 =
28+
AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue37336", out var enabled) && enabled;
29+
2730
/// <summary>
2831
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
2932
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
@@ -303,17 +306,16 @@ protected override SqlExpression VisitIn(InExpression inExpression, bool allowOp
303306

304307
/// <inheritdoc />
305308
protected override int CalculateParameterBucketSize(int count, RelationalTypeMapping elementTypeMapping)
306-
=> count switch
307-
{
308-
<= 5 => 1,
309-
<= 150 => 10,
310-
<= 750 => 50,
311-
<= 2000 => 100,
312-
<= 2070 => 10, // try not to over-pad as we approach that limit
313-
<= MaxParameterCount when UseOldBehavior37151 => 0,
314-
<= MaxParameterCount => 1, // just don't pad between 2070 and 2100, to minimize the crazy
315-
_ => 200,
316-
};
309+
{
310+
if (count <= 5) return 1;
311+
if (count <= 150) return 10;
312+
if (count <= 750) return 50;
313+
if (count <= 2000) return 100;
314+
if (count <= 2070) return 10; // try not to over-pad as we approach that limit
315+
if (count <= MaxParameterCount && UseOldBehavior37151) return 0;
316+
if (count <= MaxParameterCount) return 1; // just don't pad between 2070 and 2100, to minimize the crazy
317+
return 200;
318+
}
317319

318320
private bool TryHandleOverLimitParameters(
319321
SqlParameterExpression valuesParameter,

test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2435,6 +2435,30 @@ public virtual async Task Parameter_collection_of_ints_Contains_int_2071_values(
24352435
Assert.Contains("@ints2071)", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal);
24362436
}
24372437

2438+
[ConditionalTheory]
2439+
[InlineData(2098)]
2440+
[InlineData(2099)]
2441+
[InlineData(2100)]
2442+
public virtual Task Parameter_collection_of_ints_Contains_int_parameters_limit(int count)
2443+
{
2444+
var ints = Enumerable.Range(10, count);
2445+
2446+
// no exception from SQL Server is a pass
2447+
return AssertQuery(ss => ss.Set<PrimitiveCollectionsEntity>().Where(c => ints.Contains(c.Int)));
2448+
}
2449+
2450+
[ConditionalTheory]
2451+
[InlineData(2098)]
2452+
[InlineData(2099)]
2453+
[InlineData(2100)]
2454+
public virtual Task Parameter_collection_Count_parameters_limit(int count)
2455+
{
2456+
var ids = Enumerable.Range(1000, count);
2457+
2458+
// no exception from SQL Server is a pass
2459+
return AssertQuery(ss => ss.Set<PrimitiveCollectionsEntity>().Where(c => ids.Count(i => i > c.Id) > 0));
2460+
}
2461+
24382462
[ConditionalFact]
24392463
public virtual void Check_all_tests_overridden()
24402464
=> TestHelpers.AssertAllMethodsOverridden(GetType());

0 commit comments

Comments
 (0)