如何使用动态GroupContainer集合对DataTable执行分组与排序操作
实现动态分组排序的方案
前置依赖
确保你已经引入了以下命名空间:
using System; using System.Data; using System.Linq; using System.Collections.Generic;
第一步:实现复合键相等比较器
多列分组的键是动态的object数组,默认引用比较无法匹配值相等的场景,需要自定义比较器:
public class CompositeKeyComparer : IEqualityComparer<object[]> { public bool Equals(object[] x, object[] y) { if (x.Length != y.Length) return false; for (int i = 0; i < x.Length; i++) { if (!Equals(x[i], y[i])) return false; } return true; } public int GetHashCode(object[] obj) { int hash = 17; foreach (var item in obj) { hash = hash * 31 + (item?.GetHashCode() ?? 0); } return hash; } }
第二步:核心逻辑实现
直接基于你的GroupContainer配置集合执行动态分组和排序:
// 示例配置和数据源,替换为你自己的实例 List<GroupContainer> groupConfigs = new List<GroupContainer> { new GroupContainer{ GroupField = "col1", GroupSortOrder = "asc"}, new GroupContainer{ GroupField = "col2", GroupSortOrder = "desc"}, new GroupContainer{ GroupField = "col3", GroupSortOrder = "asc"} }; DataTable dataTable = GetYourDataTable(); // 1. 动态多列分组 var groupedData = dataTable.AsEnumerable() .GroupBy( row => groupConfigs.Select(c => row[c.GroupField]).ToArray(), new CompositeKeyComparer() ); // 2. 动态多列排序 IOrderedEnumerable<IGrouping<object[], DataRow>> sortedGroups = null; for (int i = 0; i < groupConfigs.Count; i++) { var currentConfig = groupConfigs[i]; int keyIndex = i; // 避免闭包捕获问题 if (i == 0) { sortedGroups = currentConfig.GroupSortOrder.Equals("asc", StringComparison.OrdinalIgnoreCase) ? groupedData.OrderBy(g => g.Key[keyIndex]) : groupedData.OrderByDescending(g => g.Key[keyIndex]); } else { sortedGroups = currentConfig.GroupSortOrder.Equals("asc", StringComparison.OrdinalIgnoreCase) ? sortedGroups.ThenBy(g => g.Key[keyIndex]) : sortedGroups.ThenByDescending(g => g.Key[keyIndex]); } } // 遍历结果即可使用 foreach (var group in sortedGroups) { // group.Key为分组列的取值数组,顺序和配置顺序一致 foreach (var row in group) { // 处理分组内的行数据 } }
注意事项
- 排序逻辑完全匹配
GroupSortOrder的asc/desc配置,忽略大小写 - 原生兼容
DBNull类型的列值,无需额外处理 - 如果需要对分组内的行做排序,可以参考第二步的动态排序逻辑,对每个
group单独处理即可 - 如果有极端性能要求,可以替换
CompositeKeyComparer的哈希生成逻辑降低碰撞概率
内容的提问来源于stack exchange,提问作者appootan
相关产品推荐
相关产品推荐

