最简单和最易读的方法是使用Linq-to-DataTable
:
var groups = from r in dTable.AsEnumerable()
group r by new
{
Col1 = r.Field<String>("Column1"),
Col2 = r.Field<String>("Column2"),
};
// if you only want the first row of each group:
DataTable distinctTable = groups.Select(g => g.First()).CopyToDataTable();
注意:按具有两个属性(和)的匿名类型对 进行Enumerable.GroupBy
分组,这些属性从字段和初始化。DataRows
Col1
Col2
DataRow
Column1
Column2
所以你得到了IEnumerable<DataRow>
. Enumerable.First()
返回DataRow
每个组的第一个(您也可以使用不同的方法来选择要保留的行,例如通过按日期字段排序)。
然后CopyToDataTable
从(现在)不同的 DataRows 创建一个新的 DataTable。
如果您使用的是 .NET 2,这是一个可能的实现:
IEqualityComparer<Object[]>
字典 自定义的实现:
class ObjectArrayComparer : IEqualityComparer<Object[]>
{
public bool Equals(Object[] x, Object[] y)
{
if (x == null && y == null) return true;
if (x == null || y == null) return false;
if (x.Length != y.Length) return false;
for (int i = 0; i < x.Length; i++)
{
if (x[i] == null && y[i] == null) continue;
if (x[i] == null || y[i] == null) return false;
if (!x[i].Equals(y[i])) return false;
}
return true;
}
public int GetHashCode(Object[] obj)
{
int hash = 0;
if (obj != null)
{
hash = (hash * 17) + obj.Length;
foreach (Object o in obj)
{
hash *= 17;
if (o != null) hash = hash + o.GetHashCode();
}
}
return hash;
}
}
你的RemoveDuplicateRows
方法:
public DataTable RemoveDuplicateRows(DataTable dTable, String[] colNames)
{
var hTable = new Dictionary<object[], DataRow>(new ObjectArrayComparer());
foreach (DataRow drow in dTable.Rows)
{
Object[] objects = new Object[colNames.Length];
for (int c = 0; c < colNames.Length; c++)
objects[c] = drow[colNames[c]];
if (!hTable.ContainsKey(objects))
hTable.Add(objects, drow);
}
// create a clone with the same columns and import all distinct rows
DataTable clone = dTable.Clone();
foreach (var kv in hTable)
clone.ImportRow(kv.Value);
return clone;
}
测试:
var table = new DataTable();
table.Columns.Add("Colum1", typeof(string));
table.Columns.Add("Colum2", typeof(int));
table.Columns.Add("Colum3", typeof(string));
Random r = new Random();
for (int i = 0; i < 100; i++)
{
table.Rows.Add("Colum1_" + r.Next(1, 10), r.Next(1, 10), "Colum3_" + r.Next(1, 10));
}
int rowCount = table.Rows.Count; // 100
var unique = RemoveDuplicateRows(table, new[] { "Colum1", "Colum2" });
int uniqueRowCount = unique.Rows.Count; // around 55-65