2009-10-21 32 views
6

刪除重複怎麼有我實現IEqualityComparer<DataRow>從旁邊結構DataTable刪除重複行:從數據表和自定義的IEqualityComparer <DataRow>

ID primary key, col_1, col_2, col_3, col_4 

默認的比較不起作用,因爲每一行都有它自己的,獨一無二的首要的關鍵。

如何實現IEqualityComparer<DataRow>,將跳過主鍵和唯一的數據仍比較。

我有這樣的事情:

public class DataRowComparer : IEqualityComparer<DataRow> 
{ 
public bool Equals(DataRow x, DataRow y) 
{ 
    return 
    x.ItemArray.Except(new object[] { x[x.Table.PrimaryKey[0].ColumnName] }) == 
    y.ItemArray.Except(new object[] { y[y.Table.PrimaryKey[0].ColumnName] }); 
} 

public int GetHashCode(DataRow obj) 
{ 
    return obj.ToString().GetHashCode(); 
} 
} 

public static DataTable RemoveDuplicates(this DataTable table) 
{ 
    return 
    (table.Rows.Count > 0) ? 
    table.AsEnumerable().Distinct(new DataRowComparer()).CopyToDataTable() : 
    table; 
} 

但只調用GetHashCode()並且不調用Equals()

回答

5

就是那樣Distinct作品。通常它使用GetHashCode方法。你可以編寫GetHashCode來做你所需要的。類似於

public int GetHashCode(DataRow obj) 
{ 
    var values = obj.ItemArray.Except(new object[] { obj[obj.Table.PrimaryKey[0].ColumnName] }); 
    int hash = 0; 
    foreach (var value in values) 
    { 
     hash = (hash * 397)^value.GetHashCode(); 
    } 
    return hash; 
} 

由於您更瞭解自己的數據,因此可能會想出更好的方法來生成散列。

+0

讓你的同等和散列函數同步,比如說,當哈希碼不相同時,equals永遠不會返回true。順便說一句。我的猜測是,當GetHashCode()返回相同的東西(因爲哈希會碰撞)時,仍然會調用Equals(),所以你可能會作弊並始終返回一個虛擬哈希。但不要這樣做。 – HerdplattenToni 2009-10-21 08:53:06

+3

這不僅僅是「一個好主意」,這是一個推薦的做法。 MSDN說,重載Equals類型也必須重寫GetHashCode「 – 2009-10-21 08:57:21

+0

到底爲什麼397怎麼樣使用,如果它是一個INT主鍵 – abatishchev 2009-10-21 09:17:29