按顺序排列并投射不同的对象

时间:2012-02-09 01:18:27

标签: c# .net linq sql-order-by projection

我的数据是这样的:

 Id  |  Customer  |  CartTotal
-------------------------------
 1   |      a     |     100 
 2   |      a     |     50
 3   |      b     |     110
 4   |      b     |     128

我需要按CartTotal(降序)订购它并返回不同的客户 所以我应该在我的结果集中有这个:

 Id  |  Customer  |  CartTotal
-------------------------------
  4  |      b     |     128
  1  |      a     |     100

我相信我需要做一个订单和投影。我正在使用强类型IList<>数据源。我是LINQ的新手..非常感谢任何帮助。

3 个答案:

答案 0 :(得分:4)

以下内容应该做你想要的事情:

var filteredPurchases = purchases.OrderByDescending(p => p.CartTotal)
    .GroupBy(p => p.Customer)
    .Select(g => g.First());

它将为每个CartTotal返回最多Customer的购买,从而获得所需的结果。

答案 1 :(得分:2)

到目前为止,答案是正确的,效率明显低于需要,因为它们1)在分组之前进行排序,2)首先只需要最大的元素。首先排序会生成解决方案O(n*log(n))

照顾1号,我们可以做到以下几点:

var query = purchases
    .GroupBy(p => p.Customer)
    .Select(g => g.OrderByDescending(p => p.CartTotal).First());

这为我们提供了类似O(n + n * log(n/c)的解决方案,其中c是客户数量。假设每个客户的订单大致不变,则为O(n)

现在,我们可以做得更好,只需找到每个客户的最大元素并在一次通过中选择它。不幸的是,Linq中的Max运算符使它比它应该更痛苦。如果您下拉MoreLinq,则可以执行以下操作:

var query = purchases
    .GroupBy(p => p.Customer)
    .Select(g => g.MaxBy(p => p.CartTotal));

此解决方案始终为O(n),无论向客户进行的购买分配如何。我也希望它在大型数据集上是迄今为止最快的。

答案 2 :(得分:1)

这是一个查询表达式版本:

var query = from cart in carts
            orderby cart.CartTotal descending
            group cart by cart.Customer into custCarts
            select custCarts.First();