2013-08-29 8 views
9

Ho setacciato Internet per cercare di trovare una soluzione per questo, e forse non lo farò nel modo giusto.Confronta due serie di dati - Trova modifiche - LINQ

Ho bisogno di confrontare due dataset, identici nella struttura, e vorrei trovare oggetti nuovi e modificati (usando LINQ).

Usando quello che ho trovato a CodeProject, sono riuscito a mettere insieme un elenco di elementi che sono stati modificati, ma ciò è stato fatto codificando ogni colonna (e ce ne saranno molti) e verificando i valori identici:

var updRec = from u in updated 
      join o in orig 
       on u.KeyValue equals o.KeyValue 
      where 
       (o.Propery1 != u.Propery1) || 
       (o.Propery2 != u.Propery2) 
      select new record 
      { 
       KeyValue = u.KeyValue, 
       Propery1 = u.Propery1, 
       Propery2 = u.Propery2 , 
       RecordType = "mod" // Modified 
      }; 

potevo usare aiuto con 2 cose:

  1. c'è un modo più efficiente per eseguire un ciclo attraverso ciascuna delle colonne, come ho intenzione di aggiungere molte altre proprietà che ho bisogno di confrontare ? Ci deve essere un modo migliore per controllare dinamicamente due set di dati identici per le modifiche.
  2. Come posso vedere quale propery è cambiato? Ad esempio, creando un elenco di "Proprietà, Valore Originale, Valore Aggiornato" per tutti gli articoli che non sono identici?

Speriamo che lo spieghi bene. Non esitate a indicarmi altri modi di gestire questo scenario se non lo sto guardando correttamente.

+0

È possibile eseguire l'override di 'Equals()' nell'oggetto 'record' e fare il confronto lì. Quindi puoi cambiare la clausola 'where' in' where o.Equals (u) '. Ma questo è solo spostando il confronto in un luogo più incapsulato. Se vuoi più automazione, probabilmente dovrai usare la riflessione. –

+0

Potrebbe essere necessario elencare tutte le colonne, forse proprio non conosco un modo migliore, ma so in TSQL che devi elencare tutte le colonne per confrontare i delta anche se ci sono alcuni trucchi groupby per confronti più veloci. –

+0

Come si definisce una modifica? Recentemente mi sono imbattuto in problemi simili e ho creato un metodo che combina 2 oggetti dello stesso tipo, prendendo il valore dall'oggetto di quale proprietà non è nullo o predefinito e fornisce anche un'opzione per selezionare l'oggetto prioritario, nel caso in cui entrambe le proprietà hanno un valore. Se è qualcosa che potresti desiderare, fammelo sapere e posterò una risposta con il codice e una spiegazione migliore. –

risposta

0
  1. Più veloce, ma è necessario mantenere il codice se si aggiungono nuove proprietà è necessario scrivere un comparatore personalizzato e utilizzare il proprio approccio.
  2. lento utilizzare la reflection per passare attraverso tutte le proprietà e confrontarli in modo dinamico

    IDictionary<string, Tuple<object, object>> GetDifferentProperties<T>(T keyValue1, T keyValue2) 
    { 
        var diff = new Dictionary<string, object>(); 
        foreach (var prop in typeof(T).GetProperties(BindingFlags.Public)) 
        { 
         var prop1Value = prop.GetValue(keyvalue1); 
         var prop2Value = prop.GetValue(keyValue2); 
         if (prop1Value != prop2Value) 
         diff.Add(prop.Name, Tuple.Create(prop1Value, prop2Value)); 
        } 
        return diff; 
    } 
    

e poi in voi codice

var = results = (from u in updated 
        join o in orig 
        select new 
        { 
         Value1 = o.KeyValue, 
         Value2 = u.KeyValue 
        }).ToArray() 
        .Select(x => GetDifferentProperties(x.Value1, x.Value2)) 
        .Select(DoSomestufWithDifference); 
1

È possibile utilizzare il LINQ Tranne metodo di estensione(). Ciò restituisce tutto in un elenco ad eccezione di ciò che è nella seconda lista.

var orignalContacts = GetOrignal(); 
var updatedContacts = GetUpdated(); 

var changedAndNew = updatedContacts.Except(orignalContacts); 
var unchanged  = orignalContacts.Except(updatedContacts); 

A seconda del provider di dati potrebbe essere necessario overide Equals() e GetHashCode() sui vostri oggetti.