通过DataTable的GroupBy列并计算字符串列的总和

时间:2018-08-07 10:28:39

标签: c# linq

我有以下数据表:

var dtTimephasedStatusTemp = new DataTable();
dtTimephasedStatusTemp.Columns.Add("Task Id", typeof(string));
dtTimephasedStatusTemp.Columns.Add("TimeByDay", typeof(string));
dtTimephasedStatusTemp.Columns.Add("TaskActualWork", typeof(string));
dtTimephasedStatusTemp.Columns.Add("TaskWork", typeof(string));

该表的输出如下所示。它可能具有不同的任务ID:

Task Id                                TimeByDay    TaskActualWork  TaskWork
528890be-4858-e811-a74e-b0359f8878e9    1/2/2018    8   8
528890be-4858-e811-a74e-b0359f8878e9    1/3/2018    8   8
528890be-4858-e811-a74e-b0359f8878e9    1/4/2018    8   8
528890be-4858-e811-a74e-b0359f8878e9    1/5/2018    8   8
528890be-4858-e811-a74e-b0359f8878e9    1/8/2018    8   8
528890be-4858-e811-a74e-b0359f8878e9    1/9/2018    2   2
528890be-4858-e811-a74e-b0359f8878e9    2/1/2018    0.8 0.8
528890be-4858-e811-a74e-b0359f8878e9    2/2/2018    0.8 0.8
528890be-4858-e811-a74e-b0359f8878e9    2/5/2018    0.8 0.8
528890be-4858-e811-a74e-b0359f8878e9    2/6/2018    0.8 0.8
528890be-4858-e811-a74e-b0359f8878e9    2/7/2018    5.6 5.6

我想做的是按TaskId分组并使用Linq计算TaskActualWork和TaskWork之和。我要做的是:

    DataTable dtTimephasedStatus = dtTimephasedStatusTemp.Clone();
    dtTimephasedStatus.Columns["TaskActualWork"].DataType = typeof(double);
    dtTimephasedStatus.Columns["TaskWork"].DataType = typeof(double);
    foreach (DataRow row in dtTimephasedStatusTemp.Rows)
    {
        dtTimephasedStatus.ImportRow(row);
    }

    var result = dtTimephasedStatus.AsEnumerable().
        GroupBy(x => new { TaskId = x.Field<string>("Task Id") }).
        Select(x => new
        {
            TaskId = x.Key.TaskId,
            TaskActualWorkSum = x.Sum(y => y.Field<double>("TaskActualWork")),
            TaskWorkSum = x.Sum(y => y.Field<double>("TaskWork"))
        }); 

是否还有其他方法可以使用Linq实现相同的目的?

1 个答案:

答案 0 :(得分:0)

显然,理想的解决方案是用双精度(或更好的是:小数)填充数据表,而不是首先使用字符串,但是我假设您正在使用的不是可能。

当前,您复制整个数据表只是为了更改两列的数据类型。您可以通过在对它们求和时转换这些值来避免这种情况:

var result = dtTimephasedStatusTemp.AsEnumerable().
    GroupBy(x => new { TaskId = x.Field<string>("Task Id") }).
    Select(x => new
    {
        TaskId = x.Key.TaskId,
        TaskActualWorkSum = x.Sum(y => Double.Parse(y.Field<string>("TaskActualWork"))),
        TaskWorkSum = x.Sum(y => Double.Parse(y.Field<string>("TaskWork")))
    }); 

或者,您可能需要考虑adding a new column to your data table并将其填充为循环。而且,这可能比复制整个表更有效。