我有一个简单的Forum数据结构,其中ForumPost代表了Post和答案。类/表有一个ParentId,对于帖子,它为NULL,并为答案设置。类/表还具有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和Take(1)),但没有一个起作用。
我正在使用:
对此将提供任何帮助。
答案 0 :(得分:0)
好吧,我自己找到了答案。我不确定为什么我以前没有尝试过,但是可以解决问题。重要的事情似乎不是使用First()
,而是使用FirstOrDefault()
。在这种情况下,这是没有意义的,因为查询将始终返回至少一个条目,但是使用First()
EF会在代码中进行排序,而使用FirstOrDefault()
会生成相对好的SQL查询。 / p>
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);