我正在尝试使用EF Core 3检索每个组的最新记录,但是我想到的每个可能的LINQ查询都以subtree
异常InvalidOperationException
结尾。
根据在EF Core 2.2中有效的一些答案,该查询应该可以解决问题,但不能解决问题
Processing of the LINQ expression '...' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core
我尝试过的另一个选择是
from lfv in dbo.ListingFlagValues
group lfv by lfv.ListingId into groups
select groups.OrderByDescending(x => x.Timestamp).FirstOrDefault();
我要实现的行为类似于以下查询
db.ListingFlagValues.GroupBy(x => x.Listing)
.Select(x => new { Group = x, MaxTimestamp = x.Max(y => y.Timestamp) })
.SelectMany(x => x.Group.Select(y => new { y.ListingId, ValueId = y.NewFlagValueId, y.Timestamp, x.MaxTimestamp }))
.Where(x => x.Timestamp == x.MaxTimestamp);
答案 0 :(得分:2)
此处的键为“此异常消息中可能表示EF Core中的错误或限制” (将“可能表示为表示为”)表示“)。尽管EF Core 3.0改进了查询翻译,但它仍然不支持许多查询模式,尤其是对于GroupBy
的结果。而且由于它还删除了客户端评估,因此由于无提示客户端评估而在2.x中工作的查询现在完全失败了。
另一方面,EF Core 3.0通过利用ROW_NUMBER OVER (PARTITION BY
SQL构造改进了最后一项成组模式的翻译。但是,它不适用于GroupBy
结果,因此您必须通过使用Distinct
键查询和相关子查询值手动进行分组。
例如,以下LINQ查询
from listingId in db.ListingFlagValues.Select(x => x.ListingId).Distinct()
from lfv in db.ListingFlagValues
.Where(x => x.ListingId == listingId)
.OrderByDescending(e => e.Timestamp)
.Take(1)
select lfv
使用以下SQL转换并成功执行
SELECT [t1].[Id], [t1].[ListingId], [t1].[NewFlagValueId], [t1].[Timestamp]
FROM (
SELECT DISTINCT [l].[ListingId]
FROM [ListingFlagValues] AS [l]
) AS [t]
INNER JOIN (
SELECT [t0].[Id], [t0].[ListingId], [t0].[NewFlagValueId], [t0].[Timestamp]
FROM (
SELECT [l0].[Id], [l0].[ListingId], [l0].[NewFlagValueId], [l0].[Timestamp], ROW_NUMBER() OVER(PARTITION BY [l0].[ListingId] ORDER BY [l0].[Timestamp] DESC) AS [row]
FROM [ListingFlagValues] AS [l0]
) AS [t0]
WHERE [t0].[row] <= 1
) AS [t1] ON [t].[ListingId] = [t1].[ListingId]