2012-12-27 9 views
9

Ich schreibe einen kurzen Algorithmus, der zwei DataSets vergleichen muss, damit die Unterschiede zwischen beiden weiterverarbeitet werden können. Ich versuchte dieses Ziel zu erreichen, indem ich diese zwei DataSets zusammenfasste und die resultierenden Änderungen in ein neues DataSet brachte.bekomme die Unterschiede in 2 DataSets C#

Meine Methode sieht wie folgt aus:

private DataSet ComputateDiff(DataSet newVersion, DataSet oldVersion) 
    { 
     DataSet diff = null; 
     oldVersion.Merge(newVersion); 
     bool foundChanges = oldVersion.HasChanges(); 
     if (foundChanges) 
     { 
      diff = oldVersion.GetChanges(); 
     } 
     return diff; 
    } 

Das Ergebnis foundChanges immer falsch ist, auch wenn die beiden Datensätze in es unterschiedliche Werte haben. Beide DataSets haben die gleiche Struktur. Sie bestehen aus drei DataTables, die das Ergebnis von drei Querys in einer Datenbank sind. Die Zusammenführung funktioniert gut, keine Probleme damit.

Meine Frage ist: Gibt es eine vernünftige Erklärung, warum die foundChanges Variable immer falsch ist, und wenn nicht, würde Linq eine richtige Lösung für dieses Problem bieten oder muss ich die Änderungen bestimmen, indem Sie durch die Datensätze iterieren

hier sind einige weitere Informationen: Die Programmiersprache ist C# ich bin mit .NET Framework 4.0 ich auf einem Windows-8-Maschine Die Daten entwickle wie kommt aus einer Datenbank (MSSQL Server 2012 Express) erwähnten My Datasets oder Tables haven Ich habe keine PKs, soweit ich weiß.

Vielen Dank im Voraus

+1

In der Regel nehmen Sie eine Dataset oldVersion und ändern sie. Dann würde oldVersion alle neuen Änderungen enthalten. Sie könnten dann DataSet diff = oldVersion.GetChanges() aufrufen. –

+1

Sie können dies nützlich finden: http://stackoverflow.com/a/7518025/211627 – JDB

Antwort

3

ich glaube, das Problem ist, dass Sie .NET Datasets nicht verstehen. Eine DataTable behält die "ursprüngliche" Kopie jedes Werts bei, der in es geladen wird. Wenn ein Wert geändert wird, kann die DataTable die Änderung erkennen. Ebenso verfolgt die DataTable Zeilen, die hinzugefügt oder gelöscht wurden. Die HasChanges() Funktion kriecht einfach durch die Datentabellen und überprüft, um zu sehen, ob es irgendwelche Änderungen gewesen (geänderte Wert, neue Zeilen, gelöschte Zeilen, etc.)

in der Dokumentation MSDN Siehe:
http://msdn.microsoft.com/en-us/library/system.data.dataset.haschanges.aspx

Vergleicht man zwei Datensätze ist tricky, und mir ist keine eingebaute Funktion bekannt, um dies zu handhaben (da jeder Programmierer seine eigene Definition von "Äquivalenz" haben wird).

See:

Der folgende Code wird zwei Tables vergleichen für addierte/gelöschten Zeilen suchen auf einer Schlüsselspalte basiert und geänderten Zeilen durch Vergleichen der Werte übereinstimmender Zeilen (wiederum basierend auf dem Schlüssel). Es wäre ziemlich trivial, dies zu erweitern, um DataSets zu vergleichen (indem vergleichbar benannte Tabellen zwischen DataSets verglichen werden).

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 

namespace DataSetComparison 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      var l_table1 = new DataTable(); 
      l_table1.Columns.Add("Key", typeof(int)); 
      l_table1.Columns.Add("Name", typeof(string)); 
      l_table1.Columns.Add("Age", typeof(int)); 

      var l_table2 = new DataTable(); 
      l_table2.Columns.Add("Key", typeof(int)); 
      l_table2.Columns.Add("Name", typeof(string)); 
      l_table2.Columns.Add("Age", typeof(int)); 

      l_table1.Rows.Add(l_table1.NewRow()); 
      l_table1.Rows[l_table1.Rows.Count - 1]["Key"] = 0; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Name"] = "Alfred Harisson"; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Age"] = 36; 
      l_table1.Rows.Add(l_table1.NewRow()); 
      l_table1.Rows[l_table1.Rows.Count - 1]["Key"] = 1; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Name"] = "Matthew George"; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Age"] = 41; 
      l_table1.Rows.Add(l_table1.NewRow()); 
      l_table1.Rows[l_table1.Rows.Count - 1]["Key"] = 2; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Name"] = "Franklin Henry"; 
      l_table1.Rows[l_table1.Rows.Count - 1]["Age"] = 33; 

      l_table2.Rows.Add(l_table2.NewRow()); 
      l_table2.Rows[l_table2.Rows.Count - 1]["Key"] = 0; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Name"] = "Alfred Harisson"; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Age"] = 36; 
      l_table2.Rows.Add(l_table2.NewRow()); 
      l_table2.Rows[l_table2.Rows.Count - 1]["Key"] = 1; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Name"] = "Matthew George"; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Age"] = 42; // Record 1 "modified" 
      // Record 2 "deleted" 
      // Record 3 "added": 
      l_table2.Rows.Add(l_table2.NewRow()); 
      l_table2.Rows[l_table2.Rows.Count - 1]["Key"] = 3; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Name"] = "Lester Kulick"; 
      l_table2.Rows[l_table2.Rows.Count - 1]["Age"] = 33; 

      // Using table 1 as the control, find changes in table 2 

      // Find deleted rows: 
      var l_table2Keys = l_table2.Select().Select((r) => (int) r["Key"]); 
      var l_deletedRows = l_table1.Select().Where((r) => !l_table2Keys.Contains((int) r["Key"])); 

      foreach (var l_deletedRow in l_deletedRows) 
       Console.WriteLine("Record " + l_deletedRow["Key"].ToString() + " was deleted from table 2."); 

      // Find added rows: 
      var l_table1Keys = l_table1.Select().Select((r) => (int) r["Key"]); 
      var l_addedRows = l_table2.Select().Where((r) => !l_table1Keys.Contains((int) r["Key"])); 

      foreach (var l_addedRow in l_addedRows) 
       Console.WriteLine("Record " + l_addedRow["Key"].ToString() + " was added to table 2."); 

      // Find modified rows: 
      var l_modifiedRows = l_table2.Select() 
             .Join(
              l_table1.Select(), 
              r => (int) r["Key"], 
              r => (int) r["Key"], 
              (r1, r2) => new 
               { 
                Row1 = r1, 
                Row2 = r2 
               }) 
             .Where(
              values => !(values.Row1["Name"].Equals(values.Row2["Name"]) && 
                 values.Row1["Age"].Equals(values.Row2["Age"]))) 
             .Select(values => values.Row2); 

      foreach (var l_modifiedRow in l_modifiedRows) 
       Console.WriteLine("Record " + l_modifiedRow["Key"].ToString() + " was modified in table 2."); 

      Console.WriteLine("Press any key to quit..."); 
      Console.ReadKey(true); 

     } 
    } 
} 

Console Ausgang:

Record 2 wurde aus Tabelle 2
Nehmen gelöscht 3 bis Tabelle 2.
Datensatz hinzugefügt wurde 1 in Tabelle 2 geändert wurde.

+0

Nur in der Suche. Enthält .exists könnte nützlich für Sie sein. –

+0

Cyborgx37 hat Recht, das kann man nicht so leicht machen. Sie müssten Kenntnisse über die Schlüssel des Datasets haben, sonst würden Sie nicht erkennen können, ob eine Änderung ein Update, ein Löschvorgang oder ein Einfügen ist. –

0

Wenn das Schema der beiden Datensätze gleich sind, dann können Sie unter einem

Dataset dsTest1 
DataSet dsTest2 
DataSet dsFinal; 
dsFinal.Merge(dsTest1); 
dsFinal.AcceptChanges(); 
dsFinal.Merge(dsTest2); 
DifferenceDataSet = dsFinal.GetChanges() 

versuchen Wenn das Schema der beiden Datensätze unterschiedlich sind dann Sie es manuell zu tun haben.

+0

Warum sehe ich immer wieder, dass Merge + GetChanges funktioniert, wenn nicht? –

-1

Wie Sie aus einigen der anderen Antworten sehen können, ist es nicht einfach, den Unterschied von zwei DataSets zu bekommen.

Das ist der Zweck von DataSet.GetChanges(). Wenn Sie mit einem Dataset beginnen und direkt Änderungen an diesem Dataset vornehmen (d. H. Wenn ein Benutzer eine Zelle aktualisiert, wenn ein Benutzer ein Formular sendet usw.), protokolliert das DataSet die Änderungen. Auf diese Weise können Sie DataSet.GetChanges() aufrufen, um die Änderungen (oder Unterschiede) abzurufen. Sie können dann nur die Änderungen bearbeiten.

Es ist ein schwieriges Problem, einen anfänglichen Datensatz und einen endgültigen Datensatz zu nehmen und die Unterschiede zu erhalten. Auch das Zusammenführen des endgültigen Datensatzes mit dem alten Datensatz ist nicht sinnvoll, da der endgültige Datensatz das Ergebnis der Zusammenführung ist.

Verwandte Themen