Linq使用group by获取总计

时间:2015-01-22 20:47:11

标签: c# linq sum

我有以下课程:

class Item
{
    public decimal TransactionValue { get; set; }
    public string TransactionType { get; set; }
}

我有这个清单:

        var items = new List<Item>
        {
            new Item
            {
                TransactionValue = 10,
                TransactionType = "Income"
            },
            new Item
            {
                TransactionValue = 10,
                TransactionType = "Income"
            },
            new Item
            {
                TransactionValue = -5,
                TransactionType = "Outgoing"
            },
            new Item
            {
                TransactionValue = -20,
                TransactionType = "Outgoing"
            }
        };

我正在努力获得基于ValueType的总和,我已经尝试过以下但它添加了所有内容并给了我一个总数-5,我想要的是每个交易类型的总数所以我想得到一个下面是Totals课程的新课程以及这些数据:TotalIncoming:20和TotalOutgoing: - 25.

        var r = items.Sum(x => x.TransactionValue);

class Totals
{
    public decimal TotalIncoming { get; set; }
    public decimal TotalOutgoing { get; set; }
}

由于

2 个答案:

答案 0 :(得分:1)

我确定使用Linq在一行中可能有一种聪明的方法可以做到这一点,但我能想到的一切都非常难看,所以我选择了更具可读性的东西。

var results = items.GroupBy(x => x.TransactionType)
    .ToDictionary(x => x.Key, x => x.Sum(y => y.TransactionValue));

var totals = new Totals
{
    TotalIncoming = results["Income"],
    TotalOutgoing = results["Outgoing"]
};

答案 1 :(得分:1)

您可以通过以下查询获得所需的结果: -

Totals result = new Totals
     {
        TotalIncoming = items.Where(x => x.TransactionType == "Income")
                             .Sum(x => x.TransactionValue),
        TotalOutgoing = items.Where(x => x.TransactionType == "Outgoing")
                             .Sum(x => x.TransactionValue)
     };

但是,正如您在类型Totals中看到的那样,我们需要对TransactionType进行硬编码,并且我们不知道该Sum除了使用的命名约定之外属于哪种类型的结果。

我将创建以下类型: -

class ItemTotals
{
   public string ItemType { get; set; }
   public decimal Total { get; set; }
}

在这里,我们将在结果中包含TransactionType及其对应的Total,我们可以简单地按TransactionType&amp;计算总和,这里是相同的查询: -

List<ItemTotals> query = items.GroupBy(x => x.TransactionType)
                                          .Select(x => new ItemTotals
                                          {
                                              ItemType = x.Key,
                                              Total = x.Sum(z => z.TransactionValue)
                                          }).ToList();

以下是完整的Working Fiddle,您可以从中选择。