Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checking parameter for null causes incorrect projections translation #35518

Open
elementum opened this issue Jan 23, 2025 · 1 comment
Open

Comments

@elementum
Copy link

Bug description

This is a copy of npgsql/efcore.pg#3295

Hello,

When checking a joined entity for NULL the further projecting of joined table does not take effect causing always selecting all fields and all subsequent joins if any.

Suppose having following entity hierarchy: User -> Job? -> Address

class User {
  public long Id { get; set; }
  public long? JobId { get; set; }
  // other unrelated properties
}

class Job {
 public long Id { get; set; }
 public long AddressId { get; set; }
 // other unrelated properties
}

class Address {
 public long Id { get; set; }
 // other unrelated properties
}

The following linq query

        var claim = await users
            .Select(x => new
            {
                x.Id,
                Job = x.Job == null ? null : new
                {
                    x.Job.Id,
                    Address = new
                    {
                        x.Job.Address.Id,
                        x.Job.Address.Street
                    }
                }
            })
            .Select(x => new
            {
                x.Id,
                Job = x.Job == null ? null : new
                {
                    x.Job.Id
                }
            })
            .Where(x => x.Id == 14501)
            .FirstOrDefaultAsync();

produces this sql:

SELECT c."Id", c0."Id", FALSE, c1."Id", c1."Street"
FROM "User" AS c
INNER JOIN "Job" AS c0 ON c."JobId" = c0."Id"
INNER JOIN "Address" AS c1 ON c0."AddressId" = c1."Id"
WHERE c."Id" = 14501

It includes join to Address table, even though it is not selected in the last Select method.

You may ask why doing consequent selects, the answer is the part before second select may come from elsewhere as IQueryable which you want to further narrow down.

Anyways, is that expected? And is it possible to workaround?

Your code

see description

Stack traces


Verbose output


EF Core version

9.0.0

Database provider

Npgsql.EntityFrameworkCore.PostgreSQL.9.0.1

Target framework

No response

Operating system

MAC OS

IDE

Jetbrains Rider

@cincuranet
Copy link
Contributor

Small repro:

using Microsoft.EntityFrameworkCore;

using var db = new MyContext();
Console.WriteLine(db.Users
    .Select(x => new
    {
        x.Id,
        Job = x.Job == null ? null : new
        {
            x.Job.Id,
            Address = new
            {
                x.Job.Address.Id,
                x.Job.Address.Street
            }
        }
    })
    .Select(x => new
    {
        x.Id,
        Job = x.Job == null ? null : new
        {
            x.Job.Id
        }
    })
    .Where(x => x.Id == 14501)
    .ToQueryString());

class MyContext : DbContext
{
    public DbSet<User> Users { get; set; } = null!;

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite();
    }
}
class User
{
    public long Id { get; set; }
    public long? JobId { get; set; }
    public Job? Job { get; set; }
}
class Job
{
    public long Id { get; set; }
    public long AddressId { get; set; }
    public Address Address { get; set; } = null!;
}
class Address
{
    public long Id { get; set; }
    public string Street { get; set; } = null!;
}

BTW, removing the second conditional (the x.Job == null ? null : new) "fixes" it.

@cincuranet cincuranet removed their assignment Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants