Entity framework 使用子查询对EF Core中的结果进行排序
我有一个简单的论坛数据结构,ForumPost代表帖子和答案。类/表有一个ParentId,该ID对于POST为空,对于应答为空。类/表还有一个createdAt字段。 我要做的是按照与该帖子相关的最后一个createdAt的顺序获取所有帖子。因此,如果存在答案,则应使用最新的createdBy答案来进行排序,否则应使用帖子本身的createdAt 这在SQL中很容易做到,但如果EF不生成SQL而是在代码中执行orderby,我就无法在EF Core中做到这一点 因此,简单的SQL版本应该是:Entity framework 使用子查询对EF Core中的结果进行排序,entity-framework,.net-core,Entity Framework,.net Core,我有一个简单的论坛数据结构,ForumPost代表帖子和答案。类/表有一个ParentId,该ID对于POST为空,对于应答为空。类/表还有一个createdAt字段。 我要做的是按照与该帖子相关的最后一个createdAt的顺序获取所有帖子。因此,如果存在答案,则应使用最新的createdBy答案来进行排序,否则应使用帖子本身的createdAt 这在SQL中很容易做到,但如果EF不生成SQL而是在代码中执行orderby,我就无法在EF Core中做到这一点 因此,简单的SQL版本应该是:
SELECT [u].[Id], [u].[Content], [u].[CreatedAt], [u].[CreatedById], [u].[ForumId], [u].[ModifiedAt], [u].[ModifiedById], [u].[ParentId], [u].[Sticky], [u].[Title]
FROM [ForumPosts] AS [u]
WHERE ([u].[ForumId] = 1) AND [u].[ParentId] IS NULL
ORDER BY (
SELECT MAX(tmp.CreatedAt) FROM ForumPosts AS tmp WHERE Id = u.Id OR ParentId = u.Id
) DESC;
因此,我尝试将其转换为EF代码,并得出以下结论:
this.Context.ForumPosts
.OrderByDescending(u => this.Context.ForumPosts.Where(a => a.Id == u.Id || a.ParentId == u.Id).Max(a => a.CreatedAt))
.Where(u => u.ForumId == forumId && u.ParentId == null);
但这会导致一个警告,即Max无法翻译,将在代码中执行
我尝试过其他几个版本,例如使用Select、OrderBy和Take1,但都不起作用
我正在使用:
Microsoft.NETCore.App 2.2.0
Microsoft.AspNetCore.App 2.2.0
Microsoft.EntityFrameworkCore.Design 2.2.1
在这方面的任何帮助都将不胜感激。我自己找到了答案。我不知道为什么我以前没试过,但它确实奏效了。重要的似乎不是先用,而是先用。这在szenario中没有任何意义,因为查询始终会返回至少一个条目,但使用First EF将在代码中进行排序,而使用FirstOrDefault将生成相对正常的SQL查询
this.Context.ForumPosts
.OrderByDescending(u => this.Context.ForumPosts.Where(a => a.Id == u.Id || a.ParentId == u.Id).OrderByDescending(a => a.CreatedAt).Select(a => a.CreatedAt).FirstOrDefault())
.Where(u => u.ForumId == forumId && u.ParentId == null);
在内存中检索查询数据后,始终可以执行此操作。从性能的角度来看,它可能比在数据库查询中更有效。Max是一种立即执行方法,这就是为什么它被执行而不返回查询的原因。请阅读此处了解更多信息: