Bug description
Technical Root Cause
The exception occurs because when OPENJSON is used for a nullable collection, the mapping logic fails to handle the null element within the JSON projection.
The InvalidCastException is thrown when EF Core attempts to convert a null value from the collection into a non-nullable underlying type during the command execution phase.
The UnreachableException (DebugAssert) during translation confirms that SqlServerSqlNullabilityProcessor creates a ColumnExpression with a nullable type, which is not allowed by the SqlExpression base constructor.
Generated SQL (Incorrect)
When the parameter limit (>2100) is exceeded, EF Core switches to OPENJSON but fails to account for nullability in the collection:
SQL
SELECT [e].*
FROM [Entities] AS [e]
WHERE [e].[NullableInt] IN (
SELECT [__value].[value]
FROM OPENJSON(@values) WITH ([value] int '$') AS [__value]
)
Note: In SQL Server, NULL IN (...) or Column IN (SELECT NULL) never evaluates to true. Therefore, rows where NullableInt is NULL are incorrectly excluded from the results.
Expected Behavior / SQL
The query should handle the null case by adding an OR ... IS NULL clause, ensuring consistency with how EF Core handles standard (non-OPENJSON) parameterization:
SQL
SELECT [e].*
FROM [Entities] AS [e]
WHERE [e].[NullableInt] IN (
SELECT [__value].[value]
FROM OPENJSON(@values) WITH ([value] int '$') AS [__value]
) OR [e].[NullableInt] IS NULL -- This clause should be generated when the collection contains a null
Your code
[ConditionalFact]
public virtual async Task Parameter_collection_with_null_value_Contains_null_element()
{
using var context = Fixture.CreateContext();
var values = Enumerable.Range(1, 2200).Select(i => (int?)i).ToList();
values.Add(null);
var query = await context.Set<PrimitiveCollectionsEntity>()
.Where(e => values.Contains(e.NullableInt))
.ToListAsync();
var sql = Fixture.TestSqlLoggerFactory.SqlStatements.Last();
Assert.Contains("OR [p].[NullableInt] IS NULL", sql);
}
Stack traces
1. During Execution (InvalidCastException): This error occurs when the ValueConverter attempts to process null values within the large collection during the command execution:
System.InvalidCastException : Object must implement IConvertible.
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter`2.Sanitize[T](Object value)
at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMapping.CreateParameter(DbCommand command, String name, Object value, Nullable`1 nullable, ParameterDirection direction)
at Microsoft.EntityFrameworkCore.Storage.Internal.TypeMappedRelationalParameter.AddDbParameter(DbCommand command, Object value)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
2. During SQL Processing (UnreachableException / DebugAssert): This error occurs when SqlServerSqlNullabilityProcessor attempts to build a ColumnExpression for the OPENJSON projection using a nullable type, which violates SqlExpression constraints:
System.Diagnostics.UnreachableException : Check.DebugAssert failed: SqlExpression.Type must be reference type or non-nullable value type
at Microsoft.EntityFrameworkCore.Utilities.Check.DebugAssert(Boolean condition, String message) in C:\Projects\efcore\src\Shared\Check.cs:line 114
at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlExpression..ctor(Type type, RelationalTypeMapping typeMapping) in C:\Projects\efcore\src\EFCore.Relational\Query\SqlExpressions\SqlExpression.cs:line 25
at Microsoft.EntityFrameworkCore.Query.SqlExpressions.ColumnExpression..ctor(String name, String tableAlias, Type type, RelationalTypeMapping typeMapping, Boolean nullable) in C:\Projects\efcore\src\EFCore.Relational\Query\SqlExpressions\ColumnExpression.cs:line 34
at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerSqlNullabilityProcessor.VisitIn(InExpression inExpression, Boolean allowOptimizedExpansion, Boolean& nullable) in C:\Projects\efcore\src\EFCore.SqlServer\Query\Internal\SqlServerSqlNullabilityProcessor.cs:line 264
Verbose output
Not applicable (Runtime Query Issue). Full stack trace and reproduction code provided above.
EF Core version
11.0.0-alpha.1.26064.118
Database provider
Microsoft.EntityFrameworkCore.SqlServer
Target framework
.NET 11
Operating system
Windows 11
IDE
Visual Studio 2022 17.14.16
Bug description
Technical Root Cause
The exception occurs because when OPENJSON is used for a nullable collection, the mapping logic fails to handle the null element within the JSON projection.
The InvalidCastException is thrown when EF Core attempts to convert a null value from the collection into a non-nullable underlying type during the command execution phase.
The UnreachableException (DebugAssert) during translation confirms that SqlServerSqlNullabilityProcessor creates a ColumnExpression with a nullable type, which is not allowed by the SqlExpression base constructor.
Generated SQL (Incorrect)
When the parameter limit (>2100) is exceeded, EF Core switches to OPENJSON but fails to account for nullability in the collection:
SQL
SELECT [e].*
FROM [Entities] AS [e]
WHERE [e].[NullableInt] IN (
SELECT [__value].[value]
FROM OPENJSON(@values) WITH ([value] int '$') AS [__value]
)
Note: In SQL Server, NULL IN (...) or Column IN (SELECT NULL) never evaluates to true. Therefore, rows where NullableInt is NULL are incorrectly excluded from the results.
Expected Behavior / SQL
The query should handle the null case by adding an OR ... IS NULL clause, ensuring consistency with how EF Core handles standard (non-OPENJSON) parameterization:
SQL
SELECT [e].*
FROM [Entities] AS [e]
WHERE [e].[NullableInt] IN (
SELECT [__value].[value]
FROM OPENJSON(@values) WITH ([value] int '$') AS [__value]
) OR [e].[NullableInt] IS NULL -- This clause should be generated when the collection contains a null
Your code
Stack traces
Verbose output
EF Core version
11.0.0-alpha.1.26064.118
Database provider
Microsoft.EntityFrameworkCore.SqlServer
Target framework
.NET 11
Operating system
Windows 11
IDE
Visual Studio 2022 17.14.16