Description
When Nullable Context is enabled (<Nullable>enable</Nullable>), writing a standard Where clause for a nullable string column (e.g., string?) causes either a CS8602 warning or a compilation error, creating a sub-optimal developer experience.
If we write:
C#
// CS8602: Dereference of a possibly null reference.
query = query.Where(x => x.ShortName.Contains(kw));
C# compiler generates a warning because ShortName is string?.
However, if we try to fix it using the standard C# null-safe approach:
C#
// Compiler Error: An expression tree lambda may not contain a null-propagating operator
query = query.Where(x => x.ShortName?.Contains(kw) ?? false);
The compiler blocks this because Expression Trees do not support the ?. operator yet.
Current Workarounds (And why they are unsatisfying)
-
Verbose Null Checking:
C#
query = query.Where(x => x.ShortName != null && x.ShortName.Contains(kw));
Issue: It is unnecessarily verbose, especially when chaining multiple fields (e.g., Name.Contains || ShortName.Contains || Code.Contains).
-
Using the Dammit Operator (!):
C#
query = query.Where(x => x.ShortName!.Contains(kw));
Issue: This defeats the whole purpose of enabling NRT. We are forcing the compiler to ignore a potential null, even though EF Core will safely translate this into SQL LIKE (which handles NULL gracefully in the database).
Proposal / Suggested Solution
We need a more elegant way to handle nullable properties inside EF Core LINQ queries without triggering CS8602 or resorting to !.
Ideally, either:
- C# Language Improvement: Allow null-propagating operators (
?.) inside Expression Trees so EF Core can translate them.
- EF Core Analyzer Improvement: The EF Core Roslyn Analyzer should recognize that
x.ShortName.Contains() inside an IQueryable context is safe (since SQL handles NULL propagation anyway) and suppress the CS8602 warning automatically for mapped columns.
Steps to Reproduce
- Enable
<Nullable>enable</Nullable> in .csproj.
- Define an entity with a nullable string:
public string? ShortName { get; set; }
- Attempt to query using
query.Where(x => x.ShortName.Contains(kw)).
Environment
- EF Core version: 8.0 / 9.0
- Database Provider: (e.g., Microsoft.EntityFrameworkCore.SqlServer / Pomelo.EntityFrameworkCore.MySql)
- Target Framework: .NET 8.0 / .NET 9.0
Description
When
Nullable Contextis enabled (<Nullable>enable</Nullable>), writing a standardWhereclause for a nullable string column (e.g.,string?) causes either a CS8602 warning or a compilation error, creating a sub-optimal developer experience.If we write:
C#
C# compiler generates a warning because
ShortNameisstring?.However, if we try to fix it using the standard C# null-safe approach:
C#
The compiler blocks this because Expression Trees do not support the
?.operator yet.Current Workarounds (And why they are unsatisfying)
Verbose Null Checking:
C#
Issue: It is unnecessarily verbose, especially when chaining multiple fields (e.g.,
Name.Contains || ShortName.Contains || Code.Contains).Using the Dammit Operator (
!):C#
Issue: This defeats the whole purpose of enabling NRT. We are forcing the compiler to ignore a potential null, even though EF Core will safely translate this into SQL
LIKE(which handlesNULLgracefully in the database).Proposal / Suggested Solution
We need a more elegant way to handle nullable properties inside EF Core LINQ queries without triggering CS8602 or resorting to
!.Ideally, either:
?.) inside Expression Trees so EF Core can translate them.x.ShortName.Contains()inside anIQueryablecontext is safe (since SQL handlesNULLpropagation anyway) and suppress the CS8602 warning automatically for mapped columns.Steps to Reproduce
<Nullable>enable</Nullable>in.csproj.public string? ShortName { get; set; }query.Where(x => x.ShortName.Contains(kw)).Environment