简体   繁体   English

从DataTable和自定义IEqualityComparer <DataRow>中删除重复项

[英]Remove duplicates from DataTable and custom IEqualityComparer<DataRow>

How have I to implement IEqualityComparer<DataRow> to remove duplicates rows from a DataTable with next structure: 我如何实现IEqualityComparer<DataRow>以从具有下一个结构的DataTable删除重复行:

ID primary key, col_1, col_2, col_3, col_4

The default comparer doesn't work because each row has it's own, unique primary key. 默认比较器不起作用,因为每行都有自己唯一的主键。

How to implement IEqualityComparer<DataRow> that will skip primary key and compare only data remained. 如何实现IEqualityComparer<DataRow> ,它将跳过主键并仅比较剩余的数据。

I have something like this: 我有这样的事情:

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

and

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

but it calls only GetHashCode() and doesn't call Equals() 但它只调用GetHashCode()并且不调用Equals()

That is the way Distinct works. 这就是Distinct工作方式。 Intenally it uses the GetHashCode method. 它本质上使用GetHashCode方法。 You can write the GetHashCode to do what you need. 您可以编写GetHashCode来执行您需要的操作。 Something like 就像是

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

Since you know your data better you can probably come up with a better way to generate the hash. 由于您更了解数据,因此可能会想出一种更好的方法来生成哈希。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM