简体   繁体   English

从EF Core中的子实体获取最大值

[英]Get Max from child entity in EF Core

Let's say I have Companies which have Customers which have Orders. 假设我有一些公司,这些公司的客户都有订单。 In one search query I want to set the order in a way that brings the "companies with latest orders first". 在一个搜索查询中,我希望以“带最新订单的公司优先”的方式设置订单。 (Hope this is clear enough). (希望这很清楚)。

.OrderByDescending(x =>
x.Customers.Max(c => c.Orders.Any() ? 
        y.Orders.Max(o => (DateTime?) o.DateCreatedUtc) 
        : DateTime.MinValue)
) 
  • If customer has no order consider the latest order date as DateTime.MinValue 如果客户没有订单,则将最新的订单日期视为DateTime.MinValue

Currently I'm getting this warning: The LINQ expression 'Max()' could not be translated and will be evaluated locally 目前,我收到此警告: LINQ表达式“ Max()”无法翻译,将在本地进行评估

Can we rewrite this to be evaluated on the server? 我们可以重写它以便在服务器上进行评估吗?

Initially (my apologies) it looks exactly the same as using Max() in Orderby - make sure you use nullable overloads of outer (essentially every) Max / Min calls and you get translation. 最初(我很抱歉)看起来与在Orderby中使用Max()完全相同 -确保您使用外部(基本上每个) Max / Min调用可为空的重载,然后进行翻译。

Using nullable overloads is still a must. 仍然必须使用可为空的重载。 However, there is a hidden trap. 但是,这里有一个隐藏的陷阱。 - currently EF Core can translate aggregate methods only if they use simple member selector with optional cast. -当前,EF Core只有在使用简单成员选择器和可选强制转换的情况下,才能转换聚合方法。 Any other expression is causing client evaluation regardless of the type being nullable or not. 任何其他表达式都会导致客户端评估,而不管类型是否可为空。

Fortunately there is simple solution which works for all standard aggregates except Average - flatten the aggregate set using SelectMany (could be more than one and could be combined with reference navigation properties) to the level containing the aggregating entity and apply the aggregate function on that set. 幸运的是,有一个简单的解决方案适用于除“ Average以外的所有标准聚合-使用SelectMany将聚合集(可以大于一个,可以与参考导航属性组合)展平到包含聚合实体的级别,然后在该集合上应用聚合函数。

Also make sure not using conditional or similar expressions inside the aggregate selector. 还要确保不在聚合选择器中使用条件表达式或类似表达式。 The good thing about nullable Max / Min overloads is that it returns null for empty set, so there is no need to include Any checks. 可空好事Max / Min重载是返回null的空集,所以没有必要列入Any检查。 null s normally come first in order, so normally you don't need special sentinel values. null通常按顺序排在第一位,因此通常不需要特殊的哨兵值。 And even if you do need them, make sure to apply them using C# ?? 并且即使您确实需要它们,也请确保使用C#来应用它们?? operator after the aggregate call. 聚合调用的运算符。

With all that being said, the translatable version of the sample snippet is 话虽如此,示例代码段的可翻译版本是

.OrderByDescending(x => 
    x.Customers.SelectMany(c => c.Orders).Max(o => (DateTime?)o.DateCreatedUtc))
//                  ^                                  ^
//               drill down                    convert to nullable

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM