c# - DataTable的GroupBy列并计算字符串列的总和
问题描述
我有以下数据表:
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 实现相同的目标?
解决方案
显然,理想的解决方案是首先用双精度数(或者甚至更好:小数)而不是字符串来填充数据表,但我假设您正在使用不可能的遗留系统。
目前,您复制整个数据表只是为了更改两列的数据类型。您可以通过在对它们求和时转换值来避免这种情况:
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")))
});
或者,您可能需要考虑在数据表中添加一个新列并将其填充到循环中。这也可能比复制完整的表更有效。
推荐阅读
- javascript - jQuery部分数组匹配用户输入?
- flutter - 如何找到映射到特定 pod 版本的包版本?
- javascript - 使用 AJAX 将对象从谷歌脚本分配给局部变量
- scala - /hbase/meta-region-server 的连接丢失
- java - java中无法解决的错误,有什么解决办法吗?
- python - Python random.choices() 没有给出想要的输出
- unity3d - 所有玩家的 Unity Photon Sync 硬币
- typescript - Typescript中Partial的不同实现?
- linux - Linux EC2 中的 JAVA_HOME 路径
- java - Spring Boot REST API 接受所有请求并返回空白响应