zompinc / efcore-extensions

Provides window (analytics) functions and binary functions for EF Core. Providers: SQL Server, SQLite, Postgres.
MIT License
60 stars 6 forks source link

Make AsSubQuery public #21

Open InspiringCode opened 1 month ago

InspiringCode commented 1 month ago

Hi @virzak,

is there any chance you could make DbFunctionsExtensions.AsSubQuery public?

Unfortunately, EF Core has some limitations (and there will probably always be some limitations) in regard to the way it generates SQL. I am writing a query in my current project, where I need to filter on quite a few subselect projections, which generates horribly inefficient SQL at the time (see this EF core issue).

I was trying to reimplement the AsSubQuery-functionality as a separate extension, but then I can't use your efcore-extensions anymore because we both would replace the NpgsqlQueryableMethodTranslatingExpressionVisitorFactory which doesn't work.

Since I really need this functionality (other attempts to optimize the query have failed), I am a bit out of look. What do you think?

virzak commented 1 month ago

This was explicitly recommended against by the ef core team.

Can you provide minimum repro of where the latest prerelease fails?

InspiringCode commented 1 month ago

You can take the simple example from the first post of the linked issue.

What the EF Core team meant was, that it would not be good to include AsSubQuery in the official EF Core package because the described issue should ideally be solved by the query processor.

But since there is not even a milestone yet when the query generator will be redesigned, we need a solution until then (which might be EF11, EF12 or even later).

And AsSubQuery is the only solution (workaround) I can think of.

virzak commented 1 month ago

Ok, I'll look into it on the weekend

InspiringCode commented 1 month ago
var q1 = ctx
    .Blogs
    .Select(p => new
    {
        p.Name,
        PostCount = p.Posts.Count
    })
    .AsSubQuery()
    .Where(p => p.PostCount > 5)
    .ToList();

Adding AsSubQuery to the LINQ statement above fixes the issue.

InspiringCode commented 1 month ago

@virzak Any news on this? Is there still a good argument left to not make this method public?

virzak commented 1 month ago

@InspiringCode apologies, haven't had the chance to look into this. This weekend. Promise.

In the meantime, if you can't wait, you can easily make it public yourself and throw the packages on myget or something. That's what I do while waiting for other people to resolve issues.