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

AsSplitQuery : Remove LEFT JOIN in child query when split the query and join self #31700

Closed
universorum opened this issue Sep 12, 2023 · 5 comments

Comments

@universorum
Copy link

When we split the query they include self

context.Users.Include(x => x.CreateBy)
        .Include(x => x.Orders)
        .Include(x => x.Scores)
        .AsNoTracking()
        .AsSplitQuery()
        .ToList();

It will join self in all generated query

SELECT "u"."Id", "u"."CreateById", "u0"."Id", "u0"."CreateById"
FROM "Users" AS "u"
         LEFT JOIN "Users" AS "u0" ON "u"."CreateById" = "u0"."Id"
ORDER BY "u"."Id", "u0"."Id";
SELECT "o"."Id", "o"."BuyerId", "o"."Value", "u"."Id", "u0"."Id"
FROM "Users" AS "u"
         LEFT JOIN "Users" AS "u0" ON "u"."CreateById" = "u0"."Id"
         INNER JOIN "Orders" AS "o" ON "u"."Id" = "o"."BuyerId"
ORDER BY "u"."Id", "u0"."Id";
SELECT "s"."Id", "s"."StudentId", "s"."Value", "u"."Id", "u0"."Id"
FROM "Users" AS "u"
         LEFT JOIN "Users" AS "u0" ON "u"."CreateById" = "u0"."Id"
         INNER JOIN "Score" AS "s" ON "u"."Id" = "s"."StudentId"
ORDER BY "u"."Id", "u0"."Id";

Look like it only use for sorting.
But why we need order it in all query?
Is it possible to remove that?
I think a query like this would work well:

SELECT "o"."Id", "o"."BuyerId", "o"."Value", "u"."Id"
FROM "Users" AS "u"
         INNER JOIN "Orders" AS "o" ON "u"."Id" = "o"."BuyerId"
ORDER BY "u"."Id";
SELECT "s"."Id", "s"."StudentId", "s"."Value", "u"."Id"
FROM "Users" AS "u"
         INNER JOIN "Score" AS "s" ON "u"."Id" = "s"."StudentId"
ORDER BY "u"."Id";

Repo

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;


using (var context = new MyContext())
{
    if (context.Database.EnsureCreated())
    {
        var user = new User();
        context.Users.Add(user);
        context.Users.Add(new User { CreateBy = user });
        context.SaveChanges();
    }
}


using (var context = new MyContext())
{
    var result = context.Users.Include(x => x.CreateBy)
        .Include(x => x.Orders)
        .Include(x => x.Scores)
        .AsNoTracking()
        .AsSplitQuery()
        .ToList();
}

public class MyContext : DbContext
{
    public DbSet<User>  Users  { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<Score> Score  { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) =>
        optionsBuilder.UseSqlite("Data Source=application.db;").LogTo(Console.WriteLine, LogLevel.Information);
}

public class User
{
    public int  Id         { get; set; }
    public int? CreateById { get; set; }

    public virtual User?               CreateBy { get; set; }
    public virtual ICollection<User>?  Created  { get; set; }
    public virtual ICollection<Order>? Orders   { get; set; }
    public virtual ICollection<Score>? Scores   { get; set; }
}

public class Order
{
    public int Id      { get; set; }
    public int BuyerId { get; set; }
    public int Value   { get; set; }

    public virtual required User Buyer { get; set; }
}

public class Score
{
    public int Id        { get; set; }
    public int StudentId { get; set; }
    public int Value     { get; set; }

    public virtual required User Student { get; set; }
}

Microsoft.EntityFrameworkCore 7.0.10
Microsoft.EntityFrameworkCore.Sqlite 7.0.10

Possibly related: #29182

@ajcvickers
Copy link
Member

Look like it only use for sorting. But why we need order it in all query?

Sorting is needed so that EF Core can correctly fixup the related entities after they have been returned.

@ajcvickers
Copy link
Member

See also #29171.

@stevendarby
Copy link
Contributor

Look like it only use for sorting. But why we need order it in all query?

Sorting is needed so that EF Core can correctly fixup the related entities after they have been returned.

Not for reference navigations. I believe this is a duplicate of #29182. Please upvote if you agree @universorum

@roji
Copy link
Member

roji commented Oct 4, 2023

Duplicate of #29182

@roji roji marked this as a duplicate of #29182 Oct 4, 2023
@roji roji closed this as not planned Won't fix, can't repro, duplicate, stale Oct 4, 2023
@stevendarby
Copy link
Contributor

stevendarby commented Nov 3, 2023

Sorry to be a pain @universorum, and possibly a bit cheeky of me, but I meant if you could up-vote the other open issue rather than my comment, as this would slightly increase its chances of getting fixed. (I've identified 3 other duplicates, it's a shame they can't be converted to up-votes!)

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