-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Query: query with group by in subquery produces invalid SQL #15279
Comments
Have you considered reworking it? FIRST A group by, THEN a select based on the returned data into the new object? |
@NetTecture What do you mean? My real query is something closer to the following:
Basically, I am doing the following: 1 - Use a first Select to calculate the Price and Potential with values of the Entity. 2 - Group By 1 to create only one group. 3 - Apply a second Select to calculate Result and Next I tried a few variations but I was never able to solve the client evaluation. If you have an alternative please let me know ... I would like to solve this before a fix is pushed. Thank You |
The issue here is the nested collection. You are not running group by query on products directly. You are running it on packages. i.e. for each package run Group by query. It cannot be translated to SQL GROUP BY directly and requires outer apply at best case. (Currently EF Core fails to lift it in single query and generates N+1 queries). var query = db.Set<Product>()
.Select(y => new
{
PackageId = EF.Property<int?>(y, "PackageId"),
Price = y.SalePrice * y.Coefficient / 2.4,
Potential = y.SalePrice * y.Valorization / 4.8
})
.GroupBy(p => p.PackageId)
.Select(y => new
{
Result = y.Sum(z => z.Price),
Next = y.Sum(z => z.Potential)
}).ToList(); Generated SQL SELECT SUM(([y].[SalePrice] * [y].[Coefficient]) / 2.3999999999999999E0) AS [Result], SUM(([y].[SalePrice] * [y].[Valorization]) / 4.7999999999999998E0) AS [Next]
FROM [Product] AS [y]
GROUP BY [y].[PackageId] |
@smitpatel Thank you for the answer. I have been testing your suggestion in different scenarios and it seems to solve the problem. |
Will SELECT Id, Count(Num) as ICount,
CASE WEHN Count(Id) == 0
Then 1.0
ELSE SUM(CASE WHEN Num % 2 = 0 THEN 1.0 ELSE 0.0 END) / Count(Num)
END as IRate
FROM tb
GROUP BY Id the linq should be ctx.Tb.GroupBy(x=>x.Id)
.Select(x=> new
{
Id = x.Key,
ICount = x.Count(),
IRate = x.Count() == 0 ? 1.0 : g.Sum(y=>y.Num % 2 == 0 ? 1.0 : 0.0) / x.Count()
//OR
IRate = x.Count() == 0 ? 1.0 : g.Count(y=>y.Num % 2 == 0) / x.Count()
// Count should also be translate to Sum when condition
}) |
Basic Sum in GroupBy projection is tested by GroupBy_Property_Select_Sum_Min_Key_Max_Avg. Conditionality in GroupBy is tested on key by GroupBy_aggregate_projecting_conditional_expression_based_on_group_key, #17442 also adds conditional on the aggregate function itself. |
The first query is still untested. var result = await context.Packages.Select(x => new {
Value = x.Products.GroupBy(y => 1).Select(y => new {
Result = 20
})
}).ToListAsync(); |
@smitpatel wrt case 1. after making the change the scenario is still broken - we now produce group by clause, but still there are extra columns in the subquery projection: SELECT [c].[CustomerID], [t].[c], [t].[OrderID]
FROM [Customers] AS [c]
LEFT JOIN (
SELECT SUM([o].[OrderID]) AS [c], [o].[OrderID], [o].[CustomerID]
FROM [Orders] AS [o]
GROUP BY [o].[CustomerID]
) AS [t] ON [c].[CustomerID] = [t].[CustomerID]
ORDER BY [c].[CustomerID], [t].[OrderID] |
related to/duplicate of #15873 |
I see that the milestone 3.1.0 got removed. Does this mean we shouldn't expect the issue to be fixed in 3.1.0? Thank you! |
@SebastiaanPolfliet Correct. |
@ajcvickers Any chance to get a fix into 3.1.2? This bug blocks us writing some projections which are used by OData endpoints. |
@prochnowc It's pretty unlikely that we will patch this in a 3.1.x release given the current information. Changes to the query pipeline are risky, so the customer impact of the issue would have to be very large to offset that. |
Well, here is the point of view of someone earning money with making software: I HAVE TO SHIP. You obviously do not, at least not something working, but I do have to ship. Yes, this whole post will come out as a rant - but please understand it is arant build on months of frustration with a team that seems to not understand at all that their product is USED in commercial software and contineus to not care about fixing bugs, constantly delaing them repeatedly to the next version. You talk about breaking things, for me EfCore 3.1 is in the same state ANY VERSION WAS: UNUSABLE. Seriously. Unusable except for the most simplistic cases and please do not use any feature - up before 3.1 global query filters broke the whole stack. NICE. There is nothing to break. I have projects moved to .NET Core (now 3.1) and the only way we could ever use EfCore was to load the whole table into memory on every request, then filter in memory. EfCore was fundamentally broken since I started using it in 2.1. Now you tell me that this will stay so for the foreseeable future - what are you afraid of breaking in a product that is unusable? What is the logic there? Why not make a beta release so people can try it out, like - modern software development? 3.1 solved most of the issues that forced my workaround - mostly the total inability to use global query filters by fixing the bug in there that was overlooked then deemed not worthy fixing. It introduced a "one step forward, 5 steps back" approach by ripping out core functionality and STILL not generating valid SQL and then telling people to wait. Well, I release next week. So, here is what I will do. I will rip out EfCore, the sperior product (except: it is not) and replace it with Ef non core - because THAT ONE WORKS. It may be architecturally inferior (but working), it is slower (except it is not), it has less support for non sql sources (which we do not use), it has less options for migrations (which are an antipattern for enterprise software), it has less features (but they actually WORK, not like EfCore features that are broken and should not even count) and it lacks global query filters (except there is a third party branch EntityFramework Clasic that does have them) and it has less linq features (which actually is wrong beacuse try doing a union or intersect in efcore and you realize that it only supports a VERY small subset of LINQ operations). Generally it is now - with 3 MAJOR releases of EfCore, STILL the superior product and one actually usable. You REALLY need to get a point of view outside of the "we are super, why do people complain, lets delay critical fixes" and start thinking with the view of someone who has to ship. I have tried to wait as long as I could - time to move back and accept that the best thing which happened to EfCore now is the ability to dump it. ANY bad sql bug is critial because you totally invalidate the use case for an ORM mapper if you are unable to actually use it. In any sensible world, you would put out a beta branch with fixes and see whether people complain. You would actually fix our product and not tell people ALL OVER FOR EVERY RELEASE TO WAIT FOR THE NEXT ONE. I waited for fixes to EfCore 2.1, then was told in 2.2 to wait for 3.0 then was told ithe fixes where delayed for 3.1 then NOW I read that yeah, maybe in November we fix our crappy SQL generation, please delay your products AGAIN. EfCore turned from a rework of the overengineered but working EF product into the joke of the whole stack. Maybe it turns usable before it reaches version 10 - but I actually have to ship. For anyone else who is in the same situation: I personally - i have a test project now and for every major release that is released I will check whether it FINALLY is usable there, if not - no need for me to waste my time even opening bug reports. |
This is probably not be the best place to discuss EF Core policy, but I want to answer to some points @NetTecture made that I consider valid :
All of that being said, for me, EF Core works. I've been using it continuously since 2016 and I'm very happy about it. Most of the time, it's transparent to use and doesn't get in the way. When it does, usually there's a fix, and unless you get some edge case (which happened to me) you can get your code working fast. I wouldn't go back to .Net 4 to save my life. The EF and .Net Core team are doing a tremendous job and I hope that this will continue improving going forward 👍 Feel free to move this post to a more appropriate place if needed. |
@maumar - Can you clean this up when you get time? We need to figure out action item here. |
@maumar -ping |
This issue's been here for over two years now, any progress on a fix?
This produces an error:
|
I have verified that all queries mentioned in this thread now work correctly |
We already have regression tests for most of the scenarios mentioned in the issue report. Adding the one scenario that was missing. Resolves #15279
We already have regression tests for most of the scenarios mentioned in the issue report. Adding the one scenario that was missing. Resolves #15279
We already have regression tests for most of the scenarios mentioned in the issue report. Adding the one scenario that was missing. Resolves #15279
I am running a Query with a GroupBy and it evaluates on the client.
I get the exception because I am logging all queries that evaluates on the client.
Steps to reproduce
The original query is more complex but the following one replicates the error:
Further technical details
EF Core version: 2.2.0
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: macOs Mojave 10.14.4
IDE: Visual Studio Code 1.33.0
The text was updated successfully, but these errors were encountered: