【问题标题】:GroupBy columns of DataTable and calculate sum of string columnDataTable的GroupBy列并计算字符串列的总和
【发布时间】:2018-08-07 10:28:38
【问题描述】:

我有以下数据表:

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 实现相同的目标吗?

【问题讨论】:

  • 您目前的方法有什么问题?你没有得到预期的结果吗??
  • 将字符串转换为双精度的额外 foreach 循环需要时间。如果可以的话,我只需要另一种意见。

标签: c# linq


【解决方案1】:

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

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

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 并将其填充到一个循环中。这也可能比复制完整的表格更有效。

【讨论】:

  • 你是对的,这是一个旧的遗留系统,所以任何修改都是不可能的。感谢您的建议,它将为我节省很多时间。
猜你喜欢
  • 1970-01-01
  • 2015-10-17
  • 1970-01-01
  • 2019-03-25
  • 1970-01-01
  • 1970-01-01
  • 2020-07-11
  • 2021-11-03
  • 1970-01-01
相关资源
最近更新 更多