Skip to content

Incorrect SQL translation for negated nullable boolean equality #35594

Closed as duplicate of#35393
@ixtreon

Description

@ixtreon

Description

According to C# null semantics, given a bool? A, the expressions !(A == true) and A != true should be equivalent. When used in a filter, both expressions should translate to SQL that includes rows where A is null. Previous versions of EF correctly reflected this behaviour. However, in v9, !(A == true) is incorrectly translated to SQL that excludes rows where A is null, while A != true is translated correctly.

This seems to apply to both the SQL Server and Sqlite providers.

Steps to reproduce

using Microsoft.EntityFrameworkCore;

var db = new MyContext();
var notBlocked = db.Set<User>().Where(x => !(x.IsBlocked == true)).ToQueryString();
var notBlocked2 = db.Set<User>().Where(x => x.IsBlocked != true).ToQueryString();

Console.WriteLine($"""
    Query 1:
    {notBlocked}

    Query 2:
    {notBlocked2}
    """);

class MyContext : DbContext
{
    public DbSet<User> Users { get; set; }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
        => optionsBuilder.UseSqlite();
}

class User
{
    public int Id { get; set; }
    public bool? IsBlocked { get; set; }
}

Expected Output

Using version 8.0.12 of EF and the Sqlite provider:

Query 1:
SELECT "u"."Id", "u"."IsBlocked"
FROM "Users" AS "u"
WHERE "u"."IsBlocked" = 0 OR "u"."IsBlocked" IS NULL

Query 2:
SELECT "u"."Id", "u"."IsBlocked"
FROM "Users" AS "u"
WHERE "u"."IsBlocked" <> 1 OR "u"."IsBlocked" IS NULL

Version 7.0.20 produces virtually the same output, only wrapping the IS NULL comparison in parentheses.

Actual Output

Using version 9.0.1 of EF and the Sqlite provider:

Query 1:
SELECT "u"."Id", "u"."IsBlocked"
FROM "Users" AS "u"
WHERE "u"."IsBlocked" = 0

Query 2:
SELECT "u"."Id", "u"."IsBlocked"
FROM "Users" AS "u"
WHERE "u"."IsBlocked" = 0 OR "u"."IsBlocked" IS NULL

Environment

EF Core version: 9.0.1
Database provider: Microsoft.EntityFrameworkCore.SqlServer, Microsoft.EntityFrameworkCore.Sqlite
Target framework: .NET 9.0
Operating system: Windows 11
IDE: Visual Studio 2022 17.12.3

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions