假设我有公司有客户有订单。在一个搜索查询中,我想以一种将“有最新订单的公司放在第一位”的方式设置订单。(希望这足够清楚)。
.OrderByDescending(x =>
x.Customers.Max(c => c.Orders.Any() ?
y.Orders.Max(o => (DateTime?) o.DateCreatedUtc)
: DateTime.MinValue)
)
目前我收到此警告:无法翻译 LINQ 表达式“Max()”,将在本地进行评估
我们可以重写它以在服务器上进行评估吗?
最初(我很抱歉)它看起来与在 Orderby 中使用 Max() 完全相同- 确保您使用外部(基本上是每个)Max
/Min
调用的可为空重载,并且您得到翻译。
使用可为空的重载仍然是必须的。然而,有一个隐藏的陷阱。- 目前 EF Core 只能转换聚合方法,前提是它们使用带有可选强制转换的简单成员选择器。无论类型是否可为空,任何其他表达式都会导致客户端评估。
幸运的是,有一个简单的解决方案适用于所有标准聚合,除了Average
- 将聚合集使用SelectMany
(可能不止一个并且可以与参考导航属性组合)展平到包含聚合实体的级别,并在该集合上应用聚合函数。
还要确保不在聚合选择器中使用条件或类似的表达式。可空Max
/Min
重载的好处是它返回null
空集,因此不需要包含Any
检查。null
s 通常按顺序排在最前面,所以通常你不需要特殊的哨兵值。即使您确实需要它们,也请确保在聚合调用后使用 C#??
运算符应用它们。
综上所述,示例片段的可翻译版本是
.OrderByDescending(x =>
x.Customers.SelectMany(c => c.Orders).Max(o => (DateTime?)o.DateCreatedUtc))
// ^ ^
// drill down convert to nullable
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句