-
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
OrderBy doesn't work if ThenInclude uses (or how to order nested collection) #9445
Comments
Include only determines which navigations are going to be loaded in the final projection. For your scenario you can try ordering on the client: var res = _db.Set<ApplicationUser>()
.Include(u => u.Blogs)
.ThenInclude(b => b.Posts)
.Where(u => u.Id == userId)
.ToList()
.Select(u => u.Blogs.OrderBy(b => b.Posts.OrderBy(p => p.PostOrder).First().PostOrder))
.Single(); If you want to sort on the server, then you would have to construct the projection manually (i.e. Include can't be used for this) - and this currently would produce a separate query to fetch Posts for each Blog (which is potentially very slow) |
@maumar thanks for your response. In other words, it means that for hierarchical domain model structure it's much better to have separate DbSet for each layer (i.e. DbSet<ApplicationUser>, DbSet<Blog> and DbSet<Post>) and merge data in memory. Is this efficient and idiomatic for EF? |
Given the ResultOperator @neooleg - Can you share |
@neooleg - Also
Include does not sort records in collection at present. If you want to sort records in a collection navigation property, you need to do it in memory. Given you have retrieved all the related data from server already, the sorting in memory is not huge perf hit. |
@smitpatel, sure. The main idea is that domain model is hierarchical.
Hence, for hierarchical structure -- is it make sense to have such context which should allow to query and sort on each level on server? Then combine data on transport/protocol layer.
Thanks! |
@neooleg - Thanks for info on classes. After running variety of queries with this domain,
// Query
var query = db.Set<ApplicationUser>()
.OrderBy(u => u.Blogs.OrderBy(b => b.Posts.OrderBy(p => p.PostOrder).FirstOrDefault().PostOrder).FirstOrDefault().BlogOrder)
.SingleOrDefault(u => u.Id == userId);
// SQL
SELECT TOP(2) [u].[Id]
FROM [Users] AS [u]
WHERE [u].[Id] = @__userId_0
ORDER BY (
SELECT TOP(1) [b].[BlogOrder]
FROM [Blogs] AS [b]
WHERE [u].[Id] = [b].[ApplicationUserId]
ORDER BY (
SELECT TOP(1) [p].[PostOrder]
FROM [Posts] AS [p]
WHERE [b].[Id] = [p].[BlogId]
ORDER BY [p].[PostOrder]
)
) |
closing as |
@smitpatel thanks for detailed answer! |
Steps to reproduce
There is no docs found about ordering nested collection (ThenInclude() should be used), but found some fresh samples which should work (based on discussion).
Hence using the same approach the following code should sort nested items, but it doesn't (no exception thrown):
Further technical details
EF Core version: 1.1.2
Database Provider: Doesn't work on both Microsoft.EntityFrameworkCore.SqlServer and Npgsql.EntityFrameworkCore.PostgreSQL (this is the main one)
Operating system: Windows 7 / Mac OS X 10.12.6
IDE: VS Code / Visual Studio 2017
The text was updated successfully, but these errors were encountered: