Linq左外连接与最新的日期时间在右侧

本文关键字:时间 日期 最新 连接 Linq | 更新日期: 2023-09-27 18:17:22

我有一个"Orders"表,主键是"OrderId ":

OrderId | OrderName
------- | ----------
1       | Order X
2       | Order Y  
3       | Order Z

和"OrderDetails"表,其主键为"OrderDetailsId "外键为" OrderId":

OrderDetailsId | OrderId | ItemId | DeliveryDate
-------------- | ------- | ------ | ------------
10             | 1       |   AA   | 1/1/2010
20             | 1       |   BB   | 1/1/2013
30             | 2       |   CC   | 1/1/2012
40             | 2       |   CC   | 1/1/2014

每个订单都有零个或多个订单细节,每个订单细节都有特定的交货日期。

我们想获得所有订单,无论他们是否有订单详细信息,如果订单详细信息中有最大"交货日期",则仅将一个订单标记为VIP

这是预期的输出:

OrderId | OrderName | IsVIP
------- | --------- | -----
1       | Order X   |  NO
2       | Order Y   |  YES
3       | Order Z   |  NO (since it has no order details)

这是因为OrderDetailsId = 40的最大交货日期属于OrderId = 2

如何使用最易读的LINQ代码完成此任务

Linq左外连接与最新的日期时间在右侧

我不确定你是否在orders收集中有OrderDetails属性(如果是这样,那么@juharr的答案是正确的)。但是,如果它们不是,那么你可以像这样使用group join:-

var result = from o in orders
             join od in orderDetails
             on o.OrderId equals od.OrderId into g
             select new { 
              OrderId = o.OrderId, 
              OrderName = o.OrderName,
              IsVIP = g.Any(x => x.DeliveryDate == orderDetails.Max(z => z.DeliveryDate)) 
                                                 ? "Yes" : "No" 
               };

下面是一个例子linq-to-objects摆弄

使用导航属性。注意,对于所有包含订单详细信息和最大交货日期的订单,这将把IsVIP设置为"YES"。

var query = from order in db.Orders
            select new
            {
                order.OrderId,
                order.Name,
                IsVIP = order.OrderDetails.Any(
                        od => od.DeliveryDate == db.OrderDetails.Max(x => x.DeliveryDate))
                    ? "YES"
                    : "NO"
            };