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();
}
}
và
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()
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
Đâ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. " –
tại sao chính xác 397? Cách sử dụng khóa chính nếu đó là INT? – abatishchev