C#中合并DataTable重复行并更新指定列的实现需求
合并C# DataTable中的重复行并更新列
嘿,我来帮你搞定这个DataTable合并重复行的需求!根据你给出的示例数据,我猜你是想按tid、code、pNameLocal这几个标识列来合并重复条目,然后对qty求和,同时合理处理price列(毕竟你例子里有同标识但价格不同的情况)。下面是具体的实现方案:
核心思路
- 确定分组规则:把
tid、code、pNameLocal完全相同的行归为一组(这些就是我们要合并的重复行) - 聚合列值:对每组的
qty求和;针对price,推荐用加权平均(按数量占比计算,更符合业务逻辑),如果组内价格完全一致则直接取用该值 - 生成新表:基于原表结构创建新表,把聚合后的结果写入新表(避免修改原数据,方便后续回溯)
代码实现
// 1. 按标识列分组并聚合数据 var groupedRows = dtDetails.AsEnumerable() .GroupBy(row => new { Tid = row.Field<int>("tid"), Code = row.Field<int>("code"), PNameLocal = row.Field<string>("pNameLocal") }) .Select(group => { // 对qty求和 int totalQty = group.Sum(row => row.Field<int>("qty")); // 处理price列:优先判断是否所有价格一致 var priceList = group.Select(row => row.Field<decimal>("price")).ToList(); decimal finalPrice; if (priceList.Distinct().Count() == 1) { // 所有价格相同,直接取该值 finalPrice = priceList.First(); } else { // 价格不一致,按数量加权平均(更贴合实际业务) decimal totalAmount = group.Sum(row => row.Field<decimal>("price") * row.Field<int>("qty")); finalPrice = Math.Round(totalAmount / totalQty, 2); // 可选:如果需要标记差异,可新增备注列,比如 mergedRow["note"] = "存在多档价格"; } // 创建符合原表结构的新行 DataRow mergedRow = dtDetails.NewRow(); mergedRow["id"] = group.First().Field<int>("id"); // 取分组内第一个id,也可自定义生成规则 mergedRow["tid"] = group.Key.Tid; mergedRow["code"] = group.Key.Code; mergedRow["pNameLocal"] = group.Key.PNameLocal; mergedRow["qty"] = totalQty; mergedRow["price"] = finalPrice; return mergedRow; }); // 2. 创建合并后的DataTable DataTable mergedDt = dtDetails.Clone(); // 复制原表的结构(含列定义) foreach (var row in groupedRows) { mergedDt.Rows.Add(row); } // mergedDt就是最终的合并结果啦!
补充:如果只合并完全相同的行(所有列值一致)
如果你想要的是仅合并所有列完全相同的行(比如你的示例中行2和行3),可以用下面的简化代码:
var groupedRows = dtDetails.AsEnumerable() .GroupBy(row => row.ItemArray) // 用所有列的值作为分组依据 .Select(group => { DataRow mergedRow = group.First(); // 对完全相同的行,qty求和 mergedRow["qty"] = group.Sum(r => r.Field<int>("qty")); return mergedRow; }); DataTable mergedDt = dtDetails.Clone(); foreach (var row in groupedRows) { mergedDt.ImportRow(row); }
结果说明
用第一种方案处理你的示例数据,最终合并后的结果会是:
| id | tid | code | pNameLocal | qty | price |
|---|---|---|---|---|---|
| 1 | 101 | 101 | some_local_name | 2 | 20.36 |
| 2 | 102 | 202 | some_local_name | 5 | 14.24 |
(注:14.24是按加权平均计算的结果:(15.3×1 + 15.3×1 + 10×1 + 15.3×2) ÷ 5 = 71.2 ÷ 5 = 14.24)
内容的提问来源于stack exchange,提问作者Abdul




