-
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
Bug when Take clause is used in a query and also applied to the child collections #19763
Comments
@maumar to take a look. |
repros on current master. query we generate now looks as follows: SELECT [t].[Id], [t].[Name], [t1].[Id], [t1].[Name], [t1].[EmployerId], [t1].[DepartmentId], [t1].[Id0], [t1].[Name0]
FROM (
SELECT TOP(@__p_0) [e].[Id], [e].[Name]
FROM [Employers] AS [e]
) AS [t]
OUTER APPLY (
SELECT [t].[Id], [t].[Name], [t].[EmployerId], [t].[DepartmentId], [d].[Id] AS [Id0], [d].[Name] AS [Name0]
FROM (
SELECT TOP(3) [e0].[Id], [e0].[DepartmentId], [e0].[EmployerId], [e0].[Name]
FROM [Employees] AS [e0]
WHERE [t].[Id] = [e0].[EmployerId]
) AS [t0]
INNER JOIN [Departments] AS [d] ON [t].[DepartmentId] = [d].[Id]
) AS [t1]
ORDER BY [t].[Id], [t1].[Id], [t1].[Id0] |
Perhaps same root cause as #17809 , but this repro is much lighter. |
@maumar @ajcvickers If you take a keen look at the query you posted above DepartmentId and EmployerId are not returned in the subquery aliased t - they're returned in the subquery aliased t0. That is the fix that would be needed to fix the body of the subquery aliased t1, every place where you have [t].[EmployerId] and [t].[DepartmentId] |
Same root case as #17337 |
In Complex navs. + [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Take_Select_collection_Take(bool async)
+ {
+ return AssertQuery(
+ async,
+ ss => ss.Set<Level1>().OrderBy(l1 => l1.Id).Take(1)
+ .Select(l1 => new
+ {
+ Id = l1.Id,
+ Name = l1.Name,
+ Level2s = l1.OneToMany_Required1.OrderBy(l2 => l2.Id).Take(3)
+ .Select(l2 => new
+ {
+ Id = l2.Id,
+ Name = l2.Name,
+ Level1Id = EF.Property<int>(l2, "OneToMany_Required_Inverse2Id"),
+ Level2Id = l2.Level1_Required_Id,
+ Level2 = l2.OneToOne_Required_FK_Inverse2
+ })
+ }));
+ } |
@maumar @smitpatel @ajcvickers Re-tested with Microsoft.EntityFrameworkCore 3.1.4 and Microsoft.EntityFrameworkCore 5.0.0-preview.4.20220.10 and the issue still exists. The query below looks straightforward to me so I'm wondering if there's an alternative way to re-write it in a way that it results into a valid SQL statement
|
@gathogojr This issue is not yet fixed, hence the issue is still "Open". It is in the 5.0.0 milestone, which means we plan to fix it for the EF Core 5.0 release. |
Hi @ajcvickers I see this issue has been punted. Is there any workaround we can use? var query = from blog in _dbContext.Blogs
where blog.Id == 1
let latestPosts = (from post in blog.Posts
orderby post.PostedOn descending
select post).Skip(skipPosts).Take(takePosts)
select latestPosts; Error also occures when skip is < 1 even there is no Skip / Take on parent level |
@smitpatel @maumar Any workarounds here? |
Looks like the workaround is just var query = from blog in _dbContext.Blogs
where blog.Id == 1
let latestPosts = (from post in _dbContext.BlogPosts
where post.BlogId == blog.Id
orderby post.PostedOn descending
select post).Skip(skipPosts).Take(takePosts)
select latestPosts; So use the DbSet instead of the child collection |
Note from triage: this issue is blocked by #17337. That issue is committed to be fixed in 6.0, after which this issue should also be fixed/verified fixed for 6.0. (Do not punt from 6.0.) |
I encountered something that seems related to this when querying with OData/WebApi GET /odata/blogs?$expand=Models.RssBlog/Feeds($expand=Bar;$top=0)&$top=10 Blogs is using the table-per-hierarchy strategy. The above will throw I observed the same issue with However these are fine. GET /odata/blogs?$expand=Models.RssBlog/Feeds($expand=Bar)&$top=10
GET /odata/blogs?$expand=Models.RssBlog/Feeds($expand=Bar;$top=10) I'll try to provide a demo project in the coming days |
- Don't apply Include on entities with Include already applied - Update table references when pushing down select into left for set operation - Update identifiers after applying set operation if the projection removed exiting identifiers - Update SQL references in pending collection during push down Fix for the repro in #17337 Resolves #18738 Resolves #19763 Resolves #19947 Resolves #20813 Resolves #21026 Resolves #22222 Resolves #23676 Resolves #23720
- Don't apply Include on entities with Include already applied - Update table references when pushing down select into left for set operation - Update identifiers after applying set operation if the projection removed exiting identifiers - Update SQL references in pending collection during push down Fix for the repro in #17337 Resolves #18738 Resolves #19763 Resolves #19947 Resolves #20813 Resolves #21026 Resolves #22222 Resolves #23676 Resolves #23720 Resolves #24216
- Don't apply Include on entities with Include already applied - Update table references when pushing down select into left for set operation - Update identifiers after applying set operation if the projection removed exiting identifiers - Update SQL references in pending collection during push down Fix for the repro in #17337 Resolves #18738 Resolves #19763 Resolves #19947 Resolves #20813 Resolves #21026 Resolves #22222 Resolves #23676 Resolves #23720 Resolves #24216
- Don't apply Include on entities with Include already applied - Update table references when pushing down select into left for set operation - Update identifiers after applying set operation if the projection removed exiting identifiers - Update SQL references in pending collection during push down Fix for the repro in #17337 Resolves #18738 Resolves #19763 Resolves #19947 Resolves #20813 Resolves #21026 Resolves #22222 Resolves #23676 Resolves #23720 Resolves #24216
- Don't apply Include on entities with Include already applied - Update table references when pushing down select into left for set operation - Update identifiers after applying set operation if the projection removed exiting identifiers - Update SQL references in pending collection during push down Fix for the repro in #17337 Resolves #18738 Resolves #19763 Resolves #19947 Resolves #20813 Resolves #21026 Resolves #22222 Resolves #23676 Resolves #23720 Resolves #24216
An issue was reported under the OData/WebApi project where the user complained of a breaking change after upgrading from ASP.NET Core 2.2/EF Core 2.2.6 to ASP.NET Core 3.1/EF Core 3.1.1
Link to the issue OData/WebApi#2026
Basically, the user had this Url comprising a resource path and some query options and calls to the OData service started failing (throwing an exception) after the upgrade:
/odata/Employers?$expand=Employees($expand=Department;$top=3)&$top=1
The issue was triaged by the OData Team and after further investigation it was discovered it was caused by a possible regression bug in EF Core. The user had also suspected the same. I have gone further and reproduced it in a simple Console project stripped off OData bells and whistles. This was necessary to rule out the possibility that ODL was generating an invalid LINQ expression
Steps to reproduce
Create a .NET Core (Console) project targeting .NET Core 3.1 framework and the following packages:
Add the following entity classes:
Department class:
Employee class:
Employer class:
Use fluent API to configure an entity model
Generate and run migration files to trigger creation of the database and database objects. Optionally, populate the database tables with sample data
Compose and execute the following LINQ query against the database context
Expected Result:
A list comprising at most 1 item of type Employer with a child collection of type Employee with at most 3 items
Actual Result:
Exception message:
Exception stacktrace:
Logging the generated SQL query confirms the user's observation that
EmployerId
andDepartmentId
are referencing the wrong aliases.[t].[EmployerId]
should be[t0].[EmployerId]
[t].[DepartmentId]
should be[t0].[DepartmentId]
(two locations)Query
Note that the same LINQ query runs successfully against EF Core 2.2 - 2 SQL statements are generated, one to fetch the list of parent objects and the other to fetch the child collections for each returned parent object
Here is a link to a GitHub repo reproducing the issue as described above (EF Core 3.1.1)
https://github.com/gathogojr/ODataWebApiIssue2026Repro04_EFCore311
Here's a link to a GitHub repo with a similar Console project against EF Core 2.2.6
https://github.com/gathogojr/ODataWebApiIssue2026Repro03_EFCore226
Further technical details
EF Core version: 2.2.6
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET Core 3.1
Operating system: Windows 10 Enterprise
IDE: Visual Studio 2019 16.4.3
The text was updated successfully, but these errors were encountered: