es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Comparar dos filas de DataTables mediante un identificador específico y marcarlas en consecuencia.

Tengo dos DataTables exactamente iguales (“Antiguo” y “Nuevo”) y quiero comparar las filas con el mismo identificador.

Por ejemplo, ambas DataTables (dt1, dt2) tienen una columna “ID”, por lo que quiero comparar la fila de dt1 donde “ID = 1” con la misma fila en dt2 (donde ID = 1) y ver si alguna celda es diferente en dt2 para esa fila.

dt1 (Antiguo)                |        dt2 (Nuevo)
___________________|___|___
ID, Col1, Col2            |   ID, Col1, Col2

1, "somedata", "somedata2"   |  1, "somedata", "somedata2"    -> Mismo
5, "somedata", "somedata2"   |  5, "somedata", "somedata2"    -> Mismo
90, "somedata", "somedata2"  |  90, "changed", "somedata2"   -> Cambiado
100, "somedata", "somedata2" |  100, "somedata", "changed"  -> Cambiado

Entonces quiero escribir una función que devuelva una lista de las ID’s que han cambiado (90, 100) para este ejemplo.

Agradecería cualquier ayuda.

Estoy programando en C#, por lo que me encantaría si alguien sabe cómo resolver este problema utilizando Linq.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para comparar dos DataTables y devolver los IDs de las filas que han cambiado, puedes utilizar LINQ para iterar sobre las filas del primer DataTable y compararlas con las filas correspondientes en el segundo DataTable utilizando el método “SequenceEqual”. Este método compara los valores de todas las celdas de los dos objetos DataRow y devuelve true si son iguales.

    Aquí tienes una función de ejemplo que toma dos DataTables como entrada y devuelve una lista de IDs de las filas que han cambiado:

    using System.Linq;
    
    public List<int> GetChangedIds(DataTable oldTable, DataTable newTable, string idColumnName)
    {
        List<int> changedIds = new List<int>();
        var rowsToCompare = oldTable.AsEnumerable().Where(r => newTable.AsEnumerable()
            .Any(nr => nr.Field<int>(idColumnName) == r.Field<int>(idColumnName)));
    
        foreach (DataRow row in rowsToCompare)
        {
            var matchingNewRow = newTable.AsEnumerable()
                .First(nr => nr.Field<int>(idColumnName) == row.Field<int>(idColumnName));
    
            if (!row.ItemArray.SequenceEqual(matchingNewRow.ItemArray))
            {
                changedIds.Add(row.Field<int>(idColumnName));
            }
        }
    
        return changedIds;
    }
    

    La función toma tres parámetros: el DataTable antiguo, el DataTable nuevo y el nombre de la columna de ID. Primero filtra las filas del DataTable antiguo que tienen un ID coincidente en el DataTable nuevo utilizando una consulta LINQ. Luego compara cada una de estas filas con la fila correspondiente en el DataTable nuevo utilizando el método SequenceEqual, y agrega el ID a la lista de IDs cambiados si no son iguales.

    Puedes llamar a esta función de la siguiente manera:

    DataTable oldTable = /* inicializar con datos */;
    DataTable newTable = /* inicializar con datos */;
    
    List<int> changedIds = GetChangedIds(oldTable, newTable, "ID");
    
    foreach (int id in changedIds)
    {
        Console.WriteLine($"La fila con ID {id} ha cambiado.");
    }
    

    Esto mostrará como resultado:

    La fila con ID 90 ha cambiado.
    La fila con ID 100 ha cambiado.

Comments are closed.