Skip to content

Inconsistency between C# Nullable Reference Types (NRT) and EF Core LINQ Expression Trees for optional columns #84011

@DUWENINK

Description

@DUWENINK

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)

  1. 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).

  2. 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:

  1. C# Language Improvement: Allow null-propagating operators (?.) inside Expression Trees so EF Core can translate them.
  2. 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

  1. Enable <Nullable>enable</Nullable> in .csproj.
  2. Define an entity with a nullable string: public string? ShortName { get; set; }
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions