如何在.NET Core中为动态生成的DataTable插入按客户分组的小计行
实现方案
提供两种可直接落地的实现方式,可根据你的业务场景选择:
方案1:C# 操作DataTable实现(改造成本最低)
你原有代码的问题在于:仅计算了全表总计,没有按客户分组计算,且直接把总计行加到表末尾,没有插入到对应客户分组的下方。
修正后代码如下:
private void InsertSubTotals(ref DataTable dt) { // 筛选出需要求和的日期列(排除客户、交易ID两个非数值列) var sumColumns = dt.Columns.Cast<DataColumn>() .Where(col => col.ColumnName != "Client" && col.ColumnName != "TradeId") .ToList(); // 按客户分组,倒序处理避免插入行时打乱后续分组的索引位置 var clientGroups = dt.AsEnumerable() .GroupBy(row => row["Client"].ToString()) .OrderByDescending(g => g.Max(row => dt.Rows.IndexOf(row))) .ToList(); foreach (var group in clientGroups) { DataRow subTotalRow = dt.NewRow(); subTotalRow["Client"] = group.Key; subTotalRow["TradeId"] = $"{group.Key} 小计"; // 逐列计算当前客户的分组求和值 foreach (var col in sumColumns) { int total = group.Sum(row => row.IsNull(col) ? 0 : Convert.ToInt32(row[col])); subTotalRow[col] = total; } // 把小计行插入到当前客户所有交易行的下一个位置 int lastRowIndex = dt.Rows.IndexOf(group.Last()); dt.Rows.InsertAt(subTotalRow, lastRowIndex + 1); } }
方案2:SQL层面直接生成带小计的透视结果
如果你不想修改C#逻辑,可以直接调整动态透视SQL,预先生成客户小计行再透视,查询结果直接可用于导出:
DECLARE @cols2 AS NVARCHAR(MAX), @query2 AS NVARCHAR(MAX) -- 生成动态日期列(注意替换为你实际业务中的日期字段名) select @cols2 = STUFF((SELECT ',' + QUOTENAME(BusDate) from #t2 group by BusDate order by BusDate asc FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query2 = N' SELECT Client, TradeId, ' + @cols2 + N' FROM ( -- 原始交易行,排序标记为1保证排在前面 select Client, TradeId, BusDate, Amount, 1 as SortOrder from #t2 UNION ALL -- 客户小计行,排序标记为2保证排在同客户交易行后面 select Client, Client + '' 小计'' as TradeId, BusDate, SUM(Amount) as Amount, 2 as SortOrder from #t2 group by Client, BusDate ) x pivot ( max(Amount) for BusDate in (' + @cols2 + N') ) p ORDER BY Client, SortOrder, TradeId ' exec sp_executesql @query2;
注意:上述SQL中的字段名请和你实际临时表的字段对齐,你原有代码中透视用的字段名
CPartyName/CobDate/NotionalFX和建表的Client/BusDate/Amount不一致,需替换为实际字段名。
内容的提问来源于stack exchange,提问作者Barrassment
相关产品推荐
相关产品推荐

