【问题标题】:.NET Core 3.1 - Linq - Select records grouped by a unique attribute.NET Core 3.1 - Linq - 选择按唯一属性分组的记录
【发布时间】:2020-10-26 05:24:07
【问题描述】:

在 .Net 框架中,我有这个工作查询:

IEnumerable<Cars> LatestCars = await _context.Cars.Where(x => x.IsActive == true && x.IsDeleted == false)
            .GroupBy(y => y.ManufacturerId)
            .Select(z =>
                z.OrderByDescending(k => k.ReleaseDate)
                .FirstOrDefault()
            )
            .OrderByDescending(l => l.ReleaseDate)
            .Take(5)
            .ToListAsync();

这基本上得到了不同制造商发布的最新 5 款汽车。

但是当我切换到 .NET Core 时。此查询不再起作用。运行时出现此错误:

System.InvalidOperationException: The LINQ expression '(GroupByShaperExpression:
KeySelector: (g.ManufacturerId), 
ElementSelector:(EntityShaperExpression: 
    EntityType: Cars
    ValueBufferExpression: 
        (ProjectionBindingExpression: EmptyProjectionMember)
    IsNullable: False
)
)
    .OrderByDescending(p => p.ReleaseDate)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().

你有什么建议吗?谢谢。

【问题讨论】:

标签: c# entity-framework-core


【解决方案1】:

从版本 3 开始,当表达式只能在本地执行时,EF Core 会引发异常。实际上问题不在于.OrderByDescending() 本身,而是查询包含分组这一事实,并且分组仅支持将结果聚合为标量的Select() 投影。因为只有这样才能翻译成 SQL GROUP BY 语句。

有一种方便的方法来处理这个问题。如果您有一个包含 IEnumerable&lt;Car&gt; Cars 导航属性的 Manufacturer 模型,则可以从那里开始,这会导致可翻译的查询。

因此,在您的情况下,此工作查询可能如下:

  Manufacturers.Select(m => m.Cars.OrderByDescending(c => c.ReleaseDate).FirstOrDefault())
    .OrderByDescending(c => c.ReleaseDate).Take(5)

缺点是您可以在此列表中包含 null 值,如果制造商有 0 辆汽车,那么通常最好将它们过滤掉,但在这种情况下 OrderByDescending() 几乎可以缓解这个。

另一种可能的解决方案是查询有限数量的项目,然后在本地继续工作:

  Cars.OrderByDescending(c => c.ReleaseDate).Take(100).ToList()
    .GroupBy(c => c.ManufacturerId).Select(g => g.First()).Take(5)

这样做的缺点是您最终可能会得到少于 5 个结果。

【讨论】:

    猜你喜欢
    • 2021-08-29
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    • 2023-01-18
    • 2021-09-06
    相关资源
    最近更新 更多