c# 利用IEqualityComparer接口去除DataTable重复数据
IEqualityComparer主要适用于定义方法以支持对象的相等比较。可以实现集合的自定义相等比较。即,您可以创建自己的相等定义,并指定此定义与接受 IEqualityComparer 接口的集合类型一起使用。
IEqualityComparer 接口包含两个方法
Equals 确定指定的对象是否相等。
GetHashCode 返回指定对象的哈希代码。
整体来说,比较好理解
Equals方法:自反的、对称的和可传递的。也就是说,如果此方法用于将某个对象与其自身比较,则它将返回 true;
如果对 y 和 x 执行此方法返回 true,则对 x 和 y 这两个对象也返回 true;
如果对 x 和 y 执行此方法返回 true,并且对 y 和 z 执行此方法也返回 true,则对 x 和 z 这两个对象也返回 true。
实现需要确保如果对两个对象 x 和 y 执行 Equals 方法返回 true,则对 x 和 y 分别执行 GetHashCode 方法所返回的值必须相等。
GetHashCode方法:实现需要确保如果对两个对象 x 和 y 执行 Equals 方法返回 true,则对 x 和 y 分别执行 GetHashCode 方法所返回的值必须相等。
当我们用Linq操作我们自定义的对象时,我们会发现有些方法直接使用的话根本不起作用,比如:Distinct、Except、Intersect等扩展方法。这是就需要定义IEqualityComparer接口来判断两个对象的相等性。
/// <summary> /// 按列名动态对DataTable去除重复数据,选择出不重复的行 /// </summary> /// <param name="sourceDataTable">数据源</param> /// <param name="columnNames">列名数组</param> /// <returns>返回sourceDataTable所有的列</returns> public DataTable DistinctDataTableByColumn(DataTable sourceDataTable, params string[] columnNames) { if (columnNames == null || columnNames.Length == 0) return sourceDataTable; //DataTable dt = null; //var rows = sourceDataTable.AsEnumerable().Distinct(new RowComparer(columnNames)); //if(rows.Any()) // return dt = rows.CopyToDataTable(); //return dt; return sourceDataTable.AsEnumerable().Distinct(new RowComparer(columnNames)).CopyToDataTable(); } class RowComparer : IEqualityComparer<DataRow> { private string[] _columnNames; //public RowComparer() { } public RowComparer(string[] columnNames) { this._columnNames = columnNames; } #region IEqualityComparer 成员 public bool Equals(DataRow r1, DataRow r2) { return !_columnNames.Any(colName => !r1[colName].Equals(r2[colName])); // return r1["FBFBM"].Equals(r2["FBFBM"]); } public int GetHashCode(DataRow obj) { return obj.ToString().GetHashCode(); } #endregion }
调用:
DataTable distinctDataTable= DistinctDataTableByColumn(acchelp.GetDataTable(@“select * from cbf”), "CBFBM");
过滤前:
过滤后: