2011-10-31 105 views
3

我有一些客户和相关的订单。LINQ - 使用OrderBy和GroupBy的子查询

有时我想看到每个客户的所有订单 - 足够简单。

其他时间我希望看到每个客户的最后订单,如果他们没有订单我想要看到它们。

我的继承人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) 

然后我想总所有客户最后点菜。

我不是那里,因为你可以看到 - 任何帮助真的很感激。

谢谢,乔

回答

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指的是单个订单。为了提高可读性,在查询中保留这种事情是值得的。

+0

非常好,当然谢谢 - 那么这将是一个简单的情况下通过返回的行循环获得总数? –

+0

@ Joe.Net:是的 - 但如果你只对最后的订单总数感兴趣,为什么你需要没有订单的顾客? –

+0

好的,谢谢。我需要查看客户,无论他们是否有订单或没有 - 但我可以在另一个LINQ中做到这一点,然后加入到2 .. –

1

我想虽然你可能会得到更好的使用聚合()来构建客户ID去年订单ID映射,这将避免排序和使用,你可以使用

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

只有一次扫描。

2

我打得周围,想出了:

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

DistinctBy来自飞碟双向先生对this thread

这包括你的共计“所有客户最后点菜”的要求。

干杯。

+0

非常好,谢谢 –

+0

嗨christofr - 这是不完全正确的 - 它总结客户订单,它不会汇总最后的客户订单 - 每个客户ID必须是唯一的.. –

+0

嗨,DistinctBy应该照顾 - 我已将我的代码粘贴到此处:http://pastebin.com/z8T7AMGV - 如我所料,产量为50。 – christofr