在Orderby中使用Max()

问题描述 投票:0回答:2

我有这一行,直到我启用RelationalEventId.QueryClientEvaluationWarning。

这里我们要说的是根据最新的订单日期对结果(客户)进行排序。

.OrderByDescending(x=>x.orders.Max(y=>y.CreateDate))

在配置上下文后,我意识到Max()没有转换为TSql。

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    base.OnConfiguring(optionsBuilder);
    optionsBuilder.ConfigureWarnings(warning =>
    {
        warning.Throw(RelationalEventId.QueryClientEvaluationWarning);
    });
}

错误:

InvalidOperationException: Error generated for warning 'Microsoft.EntityFrameworkCore.Query.QueryClientEvaluationWarning: The LINQ expression 'Max()' could not be translated and will be evaluated locally.

我假设在本地计算max是反对具有更好的性能。有没有办法计算SQL Server上的最大值?

c# entity-framework entity-framework-core ef-core-2.2
2个回答
2
投票

当您使用非可空类型在LINQ查询中调用聚合方法(Average,Min,Max)时,除了在本地评估它之外别无选择。

为避免这种情况,请将Max值转换为可为空的类型,并在数据库中对其进行评估。

假设CreateDate的类型为DateTime,将其转换为DateTime? (可空的)应该工作。

这是您的查询应该是什么样子:

.OrderByDescending(x=>x.orders.Max(y=> (DateTime?)y.CreateDate)) 

This answer referenced from official Github Repo


5
投票

如果您启用了EF Core Logging,您会看到以下警告:

=> Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor

可能无意中在子查询中使用潜在抛出的聚合方法(Min,Max,Average)。将使用客户端评估,如果不存在数据,则操作员将抛出。将子查询结果类型更改为可空类型将允许完全转换。

基本上他们试图在LINQ to Objects中保留上述聚合方法的抛出行为。

解决方案在最后一句话中。例如如果CreateDate的类型是DateTime,那么

.OrderByDescending(x => x.orders.Max(y => (DateTime?)y.CreateDate))

将被翻译为SQL。

© www.soinside.com 2019 - 2024. All rights reserved.