使用Order()/OrderBy()排序DataTable数据时抛出数组元素比较失败错误
问题分析与解决
错误原因
你当前代码中,Select(column => columnsToBeUnique.Select(name => column[name]))返回的是IEnumerable<IEnumerable<object>>——每一项都是由多列值组成的序列。.NET默认的比较器无法识别两个IEnumerable<object>实例的比较规则,所以调用Order()或OrderBy(x=>x)时会抛出“Failed to compare two elements in the array.”错误。
解决方案
根据你的排序需求,有几种可行的处理方式:
1. 按多列组合排序(列数固定时)
将每行的多列值转换为匿名类(匿名类自带默认比较逻辑),再按列依次排序:
var ordered = dataTable1 .AsEnumerable() .Select(row => new { // 按columnsToBeUnique的顺序定义属性 FirstCol = row[columnsToBeUnique[0]], SecondCol = row[columnsToBeUnique[1]] // 更多列依次添加 }) .OrderBy(x => x.FirstCol) .ThenBy(x => x.SecondCol) // 按第二列二次排序 // 如需还原为原始列值序列,可追加Select .Select(x => new object[] { x.FirstCol, x.SecondCol }) .ToArray();
2. 动态列数的通用排序(自定义比较器)
如果columnsToBeUnique的长度不固定,可自定义比较器来逐列比较序列元素:
// 自定义比较器类 public class EnumerableComparer : IComparer<IEnumerable<object>> { public int Compare(IEnumerable<object> x, IEnumerable<object> y) { using var enumX = x.GetEnumerator(); using var enumY = y.GetEnumerator(); while (true) { bool hasX = enumX.MoveNext(); bool hasY = enumY.MoveNext(); if (!hasX && !hasY) return 0; if (!hasX) return -1; if (!hasY) return 1; var compareResult = Comparer<object>.Default.Compare(enumX.Current, enumY.Current); if (compareResult != 0) return compareResult; } } }
使用该比较器完成排序:
var ordered = dataTable1 .AsEnumerable() .Select(row => columnsToBeUnique.Select(name => row[name]).ToList()) // 转为List避免重复枚举 .OrderBy(x => x, new EnumerableComparer()) .ToArray();
3. 按单一列排序
如果只需要按columnsToBeUnique中的某一列排序,直接指定该列即可:
var ordered = dataTable1 .AsEnumerable() .OrderBy(row => row[columnsToBeUnique[0]]) // 按第一个指定列排序 .Select(row => columnsToBeUnique.Select(name => row[name])) .ToArray();
内容的提问来源于stack exchange,提问作者Rico Strydom
相关产品推荐
相关产品推荐

