简单的LINQ DataTable聚合不起作用

时间:2016-12-01 19:32:00

标签: c# .net linq datatable data-manipulation

所以我有一个像这样的数据集:

Group   Value
A       1
A       2
B       2
B       5

我只想拥有:

Group   Value
A       3
B       7

作为另一个DataTable变量。这是我的C#代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.OleDb;
using System.Globalization;
using System.IO;
using utilityClass;

namespace testData
{
    class Program
    {
        static void Main(string[] args)
        {

            DataTable dt = new DataTable();
            string path = "test_data.csv";
            bool isFirstRowHeader = true;
            dt = Utils.GetDataTableFromCsv(path, isFirstRowHeader);

            var results = from row in dt.AsEnumerable()
                          group row by row.Field<string>("Group") into grp
                          select new
                          {
                              Id = grp.Key,
                              sum = grp.Sum(r => r.Field<int>("Value"))
                          };
            DataTable newDataTbl = results.CopyToDataTable();
        }
    }
}

它在CopyToDataTable()中给出了错误:

enter image description here

有谁知道我的代码出了什么问题?谢谢!

2 个答案:

答案 0 :(得分:1)

您的结果不是DataRows的序列。 CopyToDataTable()仅适用于IEnumerable<T> TDataRow的{​​{1}}(此link中的详细信息)。 对此有一个解决方案,您可以在引用的link中看到。要做到这一点,您将需要实现这个基于反射的解决方法:

How to: Implement CopyToDataTable Where the Generic Type T Is Not a DataRow

答案 1 :(得分:1)

通过使用where语句分配数据行对象的ItemArray并检查它是否为null,可以在from语句中创建一个数据行集合。像这样:

static void Main(string[] args)
{

    DataTable dt = new DataTable();
    string path = "test_data.csv";
    bool isFirstRowHeader = true;
    dt = Utils.GetDataTableFromCsv(path, isFirstRowHeader);
    var results = from row in dt.AsEnumerable()
                  group row by row.Field<string>("Group") into grp
                  let dr = dt.NewRow()
                  where (dr.ItemArray = new object[] { grp.Key, grp.Sum(r => r.Field<int>("Value")) }) != null
                  select dr ;
    DataTable newDataTbl = results.CopyToDataTable();
}