如何从linq查询中获取两个总和

时间:2011-11-17 19:09:33

标签: linq

摘要

我有一个交易清单。使用Linq,我想在一个查询中获得此列表中数量的成本和总和。

分组

我的第一个想法是使用分组 - 但我真的没有一个我想要分组的密钥,我只想要一个具有整个列表结果的组。所以,我碰巧有一个名为“Parent”的属性对于所有交易都是相同的,所以我用它来分组:

var totalCostQuery =
  (from t in Transactions
   where t.Status != GeneralStoreTransactionStatus.Inactive &&
   (t.Type == GeneralStoreTransactionType.Purchase ||
   t.Type == GeneralStoreTransactionType.Adjustment)
   group t by t.Parent into g
   select new
   {
     TotalCost = g.Sum(t => t.Cost.GetValueOrDefault()),
     TotalQuantity = g.Sum(t => t.Quantity.GetValueOrDefault())
   });

通过t.Parent进行分组似乎可能是错误的。我真的不想分组,我只想要t.Quantity和t.Cost的总和。

这是获得两种不同属性之和的正确方法,还是以不同的方式完成。

1 个答案:

答案 0 :(得分:2)

假设这是Linq to SQL或Entity Framework,您可以这样做:

var totalCostQuery =
  (from t in Transactions
   where t.Status != GeneralStoreTransactionStatus.Inactive &&
   (t.Type == GeneralStoreTransactionType.Purchase ||
   t.Type == GeneralStoreTransactionType.Adjustment)
   group t by 1 into g
   select new
   {
     TotalCost = g.Sum(t => t.Cost),
     TotalQuantity = g.Sum(t => t.Quantity)
   });

请注意,您不需要使用GetValueOrDefault,总和中将忽略空值。

编辑:不确定这适用于Linq到NHibernate但是......


请注意,如果您将Linq用于对象,则上述解决方案效率不高,因为它会枚举每个组两次(每次总和一次)。在这种情况下,您可以改为使用Aggregate

var transactions =
   from t in Transactions
   where t.Status != GeneralStoreTransactionStatus.Inactive &&
   (t.Type == GeneralStoreTransactionType.Purchase ||
   t.Type == GeneralStoreTransactionType.Adjustment)
   select t;

var total = 
    transactions.Aggregate(
        new { TotalCost = 0.0, TotalQuantity = 0 },
        (acc, t) =>
        {
            TotalCost = acc.TotalCost + t.Cost.GetValueOrDefault(),
            TotalQuantity = acc.TotalQuantity + t.Quantity.GetValueOrDefault(),
        });