2009-10-21 28 views
6

Làm thế nào tôi thực hiện IEqualityComparer<DataRow> để loại bỏ bản sao các hàng từ một DataTable với cấu trúc tiếp theo:Hủy bỏ bản sao từ DataTable và tùy chỉnh IEqualityComparer <DataRow>

ID primary key, col_1, col_2, col_3, col_4 

Các Comparer mặc định không làm việc vì mỗi hàng có riêng của nó, độc đáo khóa chính.

Cách triển khai IEqualityComparer<DataRow> sẽ bỏ qua khóa chính và chỉ so sánh dữ liệu duy nhất.

Tôi có một cái gì đó như thế này:

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; 
} 

nhưng nó gọi chỉ GetHashCode() và không gọi Equals()

Trả lời

5

Đó là cách Distinct công trình. Bên trong nó sử dụng phương thức GetHashCode. Bạn có thể viết GetHashCode để làm những gì bạn cần. Một cái gì đó như

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; 
} 

Vì bạn biết dữ liệu của mình tốt hơn, bạn có thể tìm ra cách tốt hơn để tạo băm.

+0

Bạn nên luôn đồng bộ hóa các hàm bằng nhau và hàm băm của mình, ví dụ: bằng không nên trả về đúng khi mã băm không giống nhau. Btw. đoán của tôi là Equals() sẽ vẫn được gọi khi GetHashCode() trả về cùng một thứ (kể từ khi băm có thể va chạm), vì vậy bạn có thể lừa dối và luôn trả về một băm giả. Nhưng đừng làm thế. – HerdplattenToni

+3

Đây không chỉ là "một ý tưởng hay", đó là một phương pháp được khuyến nghị. MSDN nói rằng các loại ghi đè bằng Equals cũng phải ghi đè lên GetHashCode. " –

+0

tại sao chính xác 397? Cách sử dụng khóa chính nếu đó là INT? – abatishchev

Các vấn đề liên quan