2009-10-21 20 views
6

¿Cómo he de implementar IEqualityComparer<DataRow> para eliminar duplicados filas de una DataTable con el siguiente estructura:eliminar duplicados de DataTable y costumbre IEqualityComparer <DataRow>

ID primary key, col_1, col_2, col_3, col_4 

El comparador predeterminado no funciona porque cada fila tiene su propio, único Clave primaria.

Cómo implementar IEqualityComparer<DataRow> que omitirá la clave principal y solo se compararán los datos.

que tienen algo como esto:

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

y

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

pero sólo llamadas GetHashCode() y no llama Equals()

Respuesta

5

Esa es la forma Distinct obras. Intenally usa el método GetHashCode. Puede escribir el GetHashCode para hacer lo que necesita. Algo así como

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

Dado que conoce mejor sus datos, probablemente pueda encontrar una forma mejor de generar el hash.

+0

Siempre es una buena idea sincronizar sus funciones iguales y hash, p. equals nunca debe volverse verdadero cuando los códigos hash no son idénticos. Por cierto. Supongo que se llamará igualmente a Equals() cuando GetHashCode() devuelva lo mismo (ya que los hash pueden colisionar), por lo que podría engañar y siempre devolver un hash ficticio. Pero no lo hagas – HerdplattenToni

+3

Esto no es solo "una buena idea", es una práctica recomendada. MSDN dice que los tipos que anulan Igual también deben anular GetHashCode. " –

+0

¿por qué exactamente 397? ¿Qué tal si usamos la clave principal si es INT? – abatishchev

Cuestiones relacionadas