使用Linq对DataTable进行GroupBy和Sum

10

你好,我有一个像这样的数据表:

Id             Amount 1        Amount 2        Amount 3  
1              2               2               2  
12             4               6               4  
12             6               6               5  
22             7               2               1  
22             7               2               2

我需要将我的数据表转换为下面这样:

Id             Amount 1        Amount 2        Amount 3  
1              2               2               2  
12             10              12              9    
22             14              4               3

我最初尝试使用匿名方法来完成它,但是我需要将其返回到另一个类中,这无法使用匿名方法完成。 我的第二次尝试是这样做以便它可以被返回:

DataTable ddt = dt.AsEnumerable()
        .Sum(g => g.Field<int>("Amount 1"))
        .GroupBy(g => new { Col1 = g["ID"] })
        .Select(g => g.OrderBy(r => r["ID"]).First())
        .CopyToDataTable();

这段代码肯定无法编译,但如果可能的话,任何帮助/建议都将不胜感激。我对linq非常陌生。


2
可能是使用LINQ对DataTable中的数据进行分组的重复问题。 - MethodMan
如果正确使用,谷歌可以成为您最好的朋友。 - MethodMan
你需要先进行分组,然后在选择语句中对每个求和。 - juharr
3个回答

29

您可以先进行 GroupBy 操作,然后将分组投影到 DataRow 中,最后使用 CopyToDataTable 扩展方法创建 DataTable

var newDt = dt.AsEnumerable()
              .GroupBy(r => r.Field<int>("Id"))
              .Select(g =>
              {
                  var row = dt.NewRow();

                  row["Id"] = g.Key;
                  row["Amount 1"] = g.Sum(r => r.Field<int>("Amount 1"));
                  row["Amount 2"] = g.Sum(r => r.Field<int>("Amount 2"));
                  row["Amount 3"] = g.Sum(r => r.Field<int>("Amount 3"));

                  return row;
              }).CopyToDataTable();

1
嗨,我使用了这段代码,但它清空了dt表格,只保留了添加的那一行?! - KiMaN
你好,这个解决方案适用于Android和Windows构建,但是当我为iOS构建时,它会抛出“不支持的异常”,就像这个问题中所述。System.Data throws NotSupportedException on iOS Unity Build 你能回答一下这个问题吗? - Çağatay Kaya

3
您正在无序地进行调用。下面的代码不会将数据放入表格中,但它将为您提供可以轻松放入表格的数据。
dt.AsEnumberable()
    .GroupBy(g => g["ID])
    .Select(g => new {
        Id = g.Key, 
        Amount1 = g.Sum(s => s.Amount1), 
        Amount2 = g.Sum(s => s.Amount2), 
        Amount3 = g.Sum(s => s.Amount3)});

2

这对我很有用。对Arturo的代码进行了轻微修改,以帮助处理如果您有小数值并使用数据表而不是变量作为数据表时出现的转换问题。(请注意,r [15]是您将要求和的列)

                  dt = dt.AsEnumerable()
                    .GroupBy(r => r["fldReportCode"])
                    .Select(g =>
                     {
                        var row = dt.NewRow();

                      row["fldReportCode"] = g.Key;
                      row[15] = g.Sum(r => (decimal)r[15]);
                      //row["Amount 2"] = g.Sum(r => r.Field<int>("Amount 2"));
                      //row["Amount 3"] = g.Sum(r => r.Field<int>("Amount 3"));

                          return row;
                      }).CopyToDataTable();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接