LINQ - 使用OrderBy和GroupBy的子查询

时间:2011-10-31 17:11:47

标签: c# linq

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

有时我想看到每个客户的所有订单 - 直截了当。

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

继承我的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 个答案:

答案 0 :(得分: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()
};

无需再执行任何分组 - 群组加入(join ... into)已经为您完成了这项任务。您正在查看单个客户的订单,因此您只需要订购它们,选择ID,然后使用FirstOrDefault()获取有序序列中的第一个值(如果序列为空,则为null)

请注意,我更改了范围变量的名称 - 在任何一点,customer表示单个客户,而order表示单个订单。为了便于阅读,在你的查询中保持这种清晰的东西是值得的。

答案 1 :(得分:2)

我正在玩耍并提出:

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

DistinctBy 来自Skeet先生this thread

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

干杯。

答案 2 :(得分:1)

我认为你可以使用

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

尽管您可能更好地使用Aggregate()将客户ID构建为最后的订单ID映射,这样可以避免排序并仅使用一次扫描。