LINQ - 使用OrderBy和GroupBy进行子查询

3

我有一些客户和相关订单。

有时我想看到每个客户的所有订单 - 这很直接。

其他时候,如果客户没有订单,我想看到他们的最后一个订单。

这是我的 LINQ 伪代码:

from customers in DataSet.Customers
join orders in DataSet.Orders on customers.CustomerId equals orders.CustomerId
into customerOrders
let customerLastOrder = customerOrders.Select(CustomerId, OrderAmount)
                                      .OrderByDescending(OrderTimestamp)
                                      .GroupBy(CustomerId)

我想要统计所有客户最近一次订单的总数。
我还没有完全实现,如您所见 - 非常感谢任何帮助。
谢谢,乔。
3个回答

4
我猜您需要:

我猜您需要:

from customer in DataSet.Customers
join order in DataSet.Orders on customer.CustomerId equals order.CustomerId
    into customerOrders
select new {
    CustomerId = customer.Id,
    LastOrderId = customerOrders.OrderByDescending(order => order.OrderTimestamp)
                                .Select(order => order.OrderId)
                                .FirstOrDefault()
};

不需要再进行任何分组操作 - group join(join ... into)已经为您完成了。您正在查看单个客户的订单,因此只需对其进行排序,选择ID,然后使用FirstOrDefault()获取有序序列中的第一个值(如果序列为空,则为null)。
请注意,我更改了您的范围变量的名称 - 在任何时候,customer都指代单个客户,而order则指代单个订单。为了提高可读性,请保持这种清晰度。

非常好,当然。谢谢 - 那么只需要循环遍历返回的行来获取总数就可以了? - Joe.Net
@Joe.Net:是的,但如果你只对最后的总订单感兴趣,为什么需要没有订单的客户呢? - Jon Skeet
好的,谢谢。我需要查看客户,无论他们是否有订单 - 但我可以在另一个LINQ代码块中完成这个操作,然后将它们连接起来。 - Joe.Net

2

我在玩耍时想到了以下内容:

var sumAmounts = Orders.OrderBy(o => o.CustomerId)
                       .ThenByDescending(o => o.DateStamp)
                       .DistinctBy(o => o.CustomerId)
                       .Sum(o => o.OrderAmount);

DistinctBy 是来自 Mr Skeet 在 这个帖子 上的。

这满足了您对“所有客户最后订单”的总计要求。

祝好。


嗨,克里斯托弗 - 这不太对 - 它会汇总所有客户订单,而不是汇总最后的客户订单 - 每个客户ID必须是唯一的。 - Joe.Net
嗨,DistinctBy应该会处理这个问题 - 我已经将我的代码粘贴到这里:http://pastebin.com/z8T7AMGV - 输出是50,正如我所期望的那样。 - christofr
啊,谢谢你的代码 - 那真的帮助了我的理解 - 如果可以的话我会点赞更多的! - Joe.Net

1

我认为你可以使用

customerOrders.OrderByDescending(OrderTimestamp)
              .GroupBy(CustomerId)
              .Select(c => new { CustomerId = c.Key, LastOrder = c.Last() });

虽然使用Aggregate()构建客户ID到最后订单ID的映射可能更好,这将避免排序并仅使用单个扫描。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接