在 Orderby 中使用 Max()
using Max() in Orderby
我有这条线一直运行到我启用 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.
我假设在本地计算最大值不利于获得更好的性能。有什么方法可以计算 SQL 服务器上的最大值吗?
当您在使用不可为 null 的类型的 LINQ 查询中调用聚合方法(Average、Min、Max)时,它别无选择,只能在本地求值。
为避免这种情况,请将您的 Max 值转换为可为 null 的类型,它将在数据库中进行评估。
假设 CreateDate 是 DateTime 类型,将其转换为 DateTime? (可为空)应该工作。
您的查询应如下所示:
.OrderByDescending(x=>x.orders.Max(y=> (DateTime?)y.CreateDate))
如果您启用了 EF Core Logging,您将看到以下警告:
=> Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor
Possible unintended use of a potentially throwing aggregate method (Min, Max, Average) in a subquery. Client evaluation will be used and operator will throw if
no data exists. Changing the subquery result type to a nullable type will allow full translation.
基本上,他们试图在 LINQ to Objects 中保留上述聚合方法的抛出行为。
解决方案在最后一句话中。例如如果 CreateDate
的类型是 DateTime
,那么
.OrderByDescending(x => x.orders.Max(y => (DateTime?)y.CreateDate))
将被翻译成 SQL。
我有这条线一直运行到我启用 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.
我假设在本地计算最大值不利于获得更好的性能。有什么方法可以计算 SQL 服务器上的最大值吗?
当您在使用不可为 null 的类型的 LINQ 查询中调用聚合方法(Average、Min、Max)时,它别无选择,只能在本地求值。
为避免这种情况,请将您的 Max 值转换为可为 null 的类型,它将在数据库中进行评估。
假设 CreateDate 是 DateTime 类型,将其转换为 DateTime? (可为空)应该工作。
您的查询应如下所示:
.OrderByDescending(x=>x.orders.Max(y=> (DateTime?)y.CreateDate))
如果您启用了 EF Core Logging,您将看到以下警告:
=> Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor
Possible unintended use of a potentially throwing aggregate method (Min, Max, Average) in a subquery. Client evaluation will be used and operator will throw if no data exists. Changing the subquery result type to a nullable type will allow full translation.
基本上,他们试图在 LINQ to Objects 中保留上述聚合方法的抛出行为。
解决方案在最后一句话中。例如如果 CreateDate
的类型是 DateTime
,那么
.OrderByDescending(x => x.orders.Max(y => (DateTime?)y.CreateDate))
将被翻译成 SQL。