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, paramsstring[] 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");
過濾前:
過濾後: