web-dev-qa-db-ger.com

Wie erhalte ich den Unterschied zwischen zwei DataTables?

Ich habe diese zwei Datentabellen und ich möchte den Unterschied zwischen ihnen herausfinden. Hier ist ein Beispiel:

Table1
-------------------------
ID  |   Name 
--------------------------
 1  |  A
 2  |  B
 3  |  C
--------------------------

Table2
-------------------------
ID  |   Name 
--------------------------
 1  |  A
 2  |  B
--------------------------

Ich möchte nur das Ergebnis als Daten, die in Tabelle1 und nicht in Tabelle2 (Tabelle1-Tabelle2) sind.

ResultTable
-------------------------
ID  |   Name 
--------------------------
 3  |  C
--------------------------

Ich habe versucht, diese beiden ähnlichen Lösungen über Linq zu verwenden, aber es wird immer table1 und nicht table1-table2 zurückgegeben. Hier ist die erste Lösung:

DataTable table1= ds.Tables["table1"];
DataTable table2= ds.Tables["table2"];
var diff= table1.AsEnumerable().Except(table2.AsEnumerable(),DataRowComparer.Default);

Zweite Lösung:

var dtOne = table1.AsEnumerable();
var dtTwo = table2.AsEnumerable();
var difference = dtOne.Except(dtTwo);

Wo ist der Fehler? Vielen Dank für alle Antworten. :)

21
user2095405

Sie können den folgenden Code ausprobieren ...

table1.AsEnumerable().Where(
    r =>!table2.AsEnumerable().Select(x=>x["ID"]).ToList().Contains(r["ID"])).ToList();
8
Amol Kolekar

Ich habe das gerade durchgemacht und wollte meine Erkenntnisse teilen. Für meine Anwendung ist es ein Datensynchronisationsmechanismus, aber ich denke, Sie werden sehen, wie sich dies auf die ursprüngliche Frage bezieht.

In meinem Fall hatte ich eine DataTable, die meinen letzten Daten-Upload darstellte, und irgendwann in der Zukunft muss ich den aktuellen Status der Daten abrufen und nur die Unterschiede hochladen.

//  get the Current state of the data
DataTable dtCurrent = GetCurrentData();

//  get the Last uploaded data
DataTable dtLast = GetLastUploadData();
dtLast.AcceptChanges();

//  the table meant to hold only the differences
DataTable dtChanges = null;

//  merge the Current DataTable into the Last DataTable, 
//  with preserve changes set to TRUE
dtLast.Merge(dtCurrent, true);

//  invoke GetChanges() with DataRowState.Unchanged
//    !! this is the key !!
//    the rows with RowState == DataRowState.Unchanged 
//    are the differences between the 2 tables
dtChanges = dtLast.GetChanges(DataRowState.Unchanged);

Ich hoffe das hilft. Ich kämpfte ein paar Stunden damit und fand viele falsche Hinweise auf dem Interwebz. Am Ende verglich ich RowStates, nachdem ich einige verschiedene Wege zusammengeführt hatte

5
Kevin.Hardy

Ich werde versuchen, dies auf einer Spaltenebene und nicht in einer DataTable zu tun. 

IEnumerable<int> id_table1 = table1.AsEnumerable().Select(val=> (int)val["ID"]);
IEnumerable<int> id_table2  = table2.AsEnumerable().Select(val=> (int)val["ID"]);
IEnumerable<int> id_notinTable1= id_table2.Except(id_table1);

Fügen Sie Ihrer Antwort einfach eine .Select() hinzu ...

1
SKJ

Versuchen Sie es unten, das ist ziemlich einfach. Fassen Sie zwei Sätze zusammen und erhalten Sie den Unterschied. Wenn sich die Sets nicht richtig ausrichten, funktioniert das nicht

DataSet firstDsData = new DataSet();
DataSet secondDsData = new DataSet();
DataSet finalDsData = new DataSet();
DataSet DifferenceDataSet = new DataSet();
finalDsData.Merge(firstDsData);
finalDsData.AcceptChanges();
finalDsData.Merge(secondDsData);
DifferenceDataSet = finalDsData.GetChanges();
1
user6826239

Versuche dies

DataTable dtmismatch = Table1.AsEnumerable().Except(Table2.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>();
0
Madhu

Versuchen Sie den folgenden Ansatz:

Initialisierung:

var columnId = new DataColumn("ID", typeof (int));
var columnName = new DataColumn("Name", typeof (string));
var table1 = new DataTable();
table1.Columns.AddRange(new[] {columnId, columnName});
table1.PrimaryKey = new[] {columnId};
table1.Rows.Add(1, "A");
table1.Rows.Add(2, "B");
table1.Rows.Add(3, "C");

var table2 = table1.Clone();
table2.Rows.Add(1, "A");
table2.Rows.Add(2, "B");
table2.Rows.Add(4, "D");

Lösung:

var table3 = table1.Copy();
table3.AcceptChanges();
table3.Merge(table2);

var distinctRows = from row in table3.AsEnumerable()
                   where row.RowState != DataRowState.Modified
                   select row;

var distintTable = distinctRows.CopyToDataTable();

Die obige Lösung funktioniert auch, wenn in table2 neue Zeilen vorhanden sind, die in table1 nicht vorhanden waren.

distintTable constainsCundD.

0
Ryszard Dżegan

Versuchen Sie es unten, das ist ziemlich einfach. Fassen Sie zwei Sätze zusammen und erhalten Sie den Unterschied. Wenn die Sets nicht richtig ausgerichtet sind, funktioniert dies nicht. 

DataSet firstDsData = new DataSet();
DataSet secondDsData = new DataSet();
DataSet finalDsData = new DataSet();
DataSet DifferenceDataSet = new DataSet();
finalDsData.Merge(firstDsData);
finalDsData.AcceptChanges();
finalDsData.Merge(secondDsData);
DifferenceDataSet = finalDsData.GetChanges();
0
TGarrett