diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs index 1e7b0507ad2..d4b1819d21d 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs @@ -16,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; /// public class SqlServerSqlNullabilityProcessor : SqlNullabilityProcessor { - private const int MaxParameterCount = 2100; + private int MaxParameterCount => UseOldBehavior37336 ? 2100 : 2100 - 2; private static readonly bool UseOldBehavior37151 = AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue37151", out var enabled) && enabled; @@ -24,6 +24,9 @@ public class SqlServerSqlNullabilityProcessor : SqlNullabilityProcessor private static readonly bool UseOldBehavior37185 = AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue37185", out var enabled) && enabled; + private static readonly bool UseOldBehavior37336 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue37336", out var enabled) && enabled; + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// 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 /// protected override int CalculateParameterBucketSize(int count, RelationalTypeMapping elementTypeMapping) - => count switch - { - <= 5 => 1, - <= 150 => 10, - <= 750 => 50, - <= 2000 => 100, - <= 2070 => 10, // try not to over-pad as we approach that limit - <= MaxParameterCount when UseOldBehavior37151 => 0, - <= MaxParameterCount => 1, // just don't pad between 2070 and 2100, to minimize the crazy - _ => 200, - }; + { + if (count <= 5) return 1; + if (count <= 150) return 10; + if (count <= 750) return 50; + if (count <= 2000) return 100; + if (count <= 2070) return 10; // try not to over-pad as we approach that limit + if (count <= MaxParameterCount && UseOldBehavior37151) return 0; + if (count <= MaxParameterCount) return 1; // just don't pad between 2070 and 2100, to minimize the crazy + return 200; + } private bool TryHandleOverLimitParameters( SqlParameterExpression valuesParameter, diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs index d959d170c78..0709a396445 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs @@ -2420,6 +2420,30 @@ public virtual async Task Parameter_collection_of_ints_Contains_int_2071_values( Assert.Contains("@ints2071)", Fixture.TestSqlLoggerFactory.SqlStatements[0], StringComparison.Ordinal); } + [ConditionalTheory] + [InlineData(2098)] + [InlineData(2099)] + [InlineData(2100)] + public virtual Task Parameter_collection_of_ints_Contains_int_parameters_limit(int count) + { + var ints = Enumerable.Range(10, count); + + // no exception from SQL Server is a pass + return AssertQuery(ss => ss.Set().Where(c => ints.Contains(c.Int))); + } + + [ConditionalTheory] + [InlineData(2098)] + [InlineData(2099)] + [InlineData(2100)] + public virtual Task Parameter_collection_Count_parameters_limit(int count) + { + var ids = Enumerable.Range(1000, count); + + // no exception from SQL Server is a pass + return AssertQuery(ss => ss.Set().Where(c => ids.Count(i => i > c.Id) > 0)); + } + [ConditionalFact] public virtual void Check_all_tests_overridden() => TestHelpers.AssertAllMethodsOverridden(GetType());