2 DataTables mit einander vergleichen?

Gotenks

Mitglied
Hallo @ all...

habe ein neues Anliegen :)

Also ich wollte mal fragen, wie ist es möglich, dass ich zwei DataTables mit einander vergleichen kann?
In einem DataTable(A) sind Daten abgelegt(Eine Tabelle) und das zweite DataTable(B) ist momentan leer.

Jetzt möchte ich das DT B mit DT A verglichen wird und wenn es dort Datensätze/Zeilen gibt die in DT B nicht vorhanden sind, weil DT A regelmäßig mit der Datenbank kommuniziert, sollen diese Datensätze/zeilen in DT B geschrieben werden.

Und diese Aktion soll er jedesmal durchgeführt werden, SOBALD ich z.B. ein Button-Klicke oder was eingebe. Dies kann dazu führen, dass in DT A schon neue Datensätze/Zeile vorhanden sind, aber ich noch in DT B die alten Datensätze/zeilen habe..UND SO WILL CIH DAS AUCH ^^

Ist sowas möglich?


Wenn ja würde ich mich über jegliche Hilfe freuen :)

Edit: Falls es euch weiter hild DT A besitzt eine ID spalte und die besieht er von der Datenbank, also gibt es dort keine überschneidungen :D
 
Zuletzt bearbeitet:

rd4eva

Erfahrenes Mitglied
Ich würde mal behaupten da bist du mit Linq am besten beraten.
Hier mal 2 Beispiele wie du es angehen kannst.
C#:
DataRow[] diff = tableA.Select("id not in (" + 
                                                string.Join(",", 
                                                    tableB.AsEnumerable()
                                                            .Select(x => x["id"])
                                                            .ToArray()
                                                            ) + 
                                            ")");
Oder etwas kürzer
C#:
DataRow[] diff2 = tableA.AsEnumerable()
                                    .Where(x => 
                                            tableB.Select("id = " + x["id"])
                                                    .Length == 0
                                            ).ToArray();
 

Gotenks

Mitglied
Heyy :)

Danke, aber mein mir funktoniert das ganze nicht :/
Hier ist mal mein Code:
C#:
        private void button3_Click(object sender, EventArgs e)
        {
            DataTable a_table = result.Tables[0];
            DataTable b_table = result.Tables[1];
            DataTable haupt_DT = tables.result_DT(a_table, b_table);
            DataTable temp_DT = tables.temp_DT();

            DataColumn[] primArray = new DataColumn[1];
            primArray[0] = haupt_DT.Columns["ID"];
            haupt_DT.PrimaryKey = primArray;

            DataRow[] diff2 = temp_DT.AsEnumerable()
                                                .Where(x =>
                                                        haupt_DT.Select("id = " + x["id"])
                                                                .Length == 0
                                                        ).ToArray();

            dataGridView1.DataSource = temp_DT;
            DataGridViewCheckBoxColumn checkBox = new DataGridViewCheckBoxColumn();
            checkBox.HeaderText = "Speichern";
            checkBox.Name = "Speichern";
            checkBox.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
            dataGridView1.Columns.Insert(0, checkBox);
            dataGridView1.AutoGenerateColumns = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DataTable temp_DT = tables.temp_DT();

            dataGridView1.DataSource = temp_DT;  
        }

Es zeigt immer nur Error an oder es werden keine Datensätze angezeigt :(

Wie man bei FORM1 load zieht, soll er bei jedem winform start, die temp_DT laden(und die datensätze seit dem letzten button3_click anzeigt/speichert), wo momenan nichts drinne ist.

Doch ich bekomme das temp_DT nicht gefüllt, habe es mit merge-methode versucht, doch die kopiert zwar die datensätze in temp_DT doch speichern tut er sich nicht rein :/
 
Zuletzt bearbeitet:

rd4eva

Erfahrenes Mitglied
Es zeigt immer nur Error an oder es werden keine Datensätze angezeigt
Ich behaupte mal das du eine Aussagekräftigere Fehlermeldung kriegst als einfach nur Error.

Soweit ich in deinem Code durchsehe hast du hier temp_DT und haupt_DT vertauscht (Das sollte aber zu keinem Fehler führen sondern nur ein Logik Fehler sein):
C#:
DataRow[] diff2 = temp_DT.AsEnumerable()
                                                .Where(x =>
                                                        haupt_DT.Select("id = " + x["id"])
                                                                .Length == 0
                                                        ).ToArray();

Alles in allem kann ich mit dem Code fragment aber nicht viel anfangen.
Also ein bisl Kontext und eine ordentliche Fehlermeldung wären schön.
 

Gotenks

Mitglied
Heyyy :D

Also dieses Error kam, wegen einem Fehler, dass wurde bereinigt.

Doch wenn ich auch beide Felder temp_DT und haupt_DT tausche passiert nichts...

Wenn die WinForms geladen ist, zeigt er die Spaltennamen des temp_DT an, sobald ich auf button3_click, klicke erscheint nur die checkbox column die ich dem datagridview selbst hinzugefügt habe. und keines der Spalten wir ergänzt :(

Und eine Fehlermeldung gibt es nicht mehr, er startet die Aplikation ganz normal und wenn ich auf den ButtonKlicke kommt kein JIT-Fehler... Momentan bin ich sowieso am verzwifeln :/.. weiß echt nicht woran das leigt :/
 

rd4eva

Erfahrenes Mitglied
Sorry aber wenn du mir nicht mehr Code gibst kann ich dir nicht helfen.

Den einzigen Tipp den ich dir geben kann ist : debuggen.
Setz dir einen Breakpoint in den Klick eventhandler und steppe einzeln durch um zu sehen ob die Variablen die Werte enthalten die du erwartest.
 

Gotenks

Mitglied
Du willst Code du bekommst Code :D

C#:
private void button3_Click(object sender, EventArgs e)
        {
            SqlConnection a_Conn = new SqlConnection(aconStr);
            SqlConnection b_Conn = new SqlConnection(bconStr);

            SqlDataAdapter a_dataAdapter = new SqlDataAdapter(aSelectStr,a_Conn);
            SqlDataAdapter b_dataAdapter = new SqlDataAdapter(bSelectStr, b_Conn);

            a_Conn.Open();
            b_Conn.Open();

            DataSet result = new DataSet();
            a_dataAdapter.FillSchema(result, SchemaType.Source, "daten");
            b_dataAdapter.FillSchema(result, SchemaType.Source, "bank");
            a_dataAdapter.Fill(result, "daten");
            b_dataAdapter.Fill(result, "bank");

            a_Conn.Close();
            b_Conn.Close();

            DataTable a_table = result.Tables[0];
            DataTable b_table = result.Tables[1];
            DataTable haupt_DT = tables.result_DT(a_table, b_table);  //in dieser methode werden die bei datatables miteinander verbunden, mittels LINQ to DataSet, diese Datatable holt die daten vom DB und sind immer aktuell.
            DataTable temp_DT = tables.temp_DT(); // hier sollen die daten nach klicken gespeichert werden

            DataColumn[] primArray = new DataColumn[1];
            primArray[0] = haupt_DT.Columns["ID"];
            haupt_DT.PrimaryKey = primArray;

            DataRow[] diff2 = haupt_DT.AsEnumerable()
                                                .Where(x =>
                                                        temp_DT.Select("id = " + x["id"])
                                                                .Length == 0
                                                        ).ToArray();


            dataGridView1.DataSource = temp_DT; // hier sollen die datensätze angezeigt werden
            DataGridViewCheckBoxColumn checkBox = new DataGridViewCheckBoxColumn();
            checkBox.HeaderText = "Speichern";
            checkBox.Name = "Speichern";
            checkBox.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
            dataGridView1.Columns.Insert(0, checkBox);
            dataGridView1.AutoGenerateColumns = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DataTable temp_DT = tables.temp_DT();

            dataGridView1.DataSource = temp_DT;   // bei jeden form start soll der "letztestand" angezeigt werden, also der stand wo ich das letzte mal button geklickt habe.
        }

So nun hoffe ich kannst du mir besser weiter helfen :)
 
Zuletzt bearbeitet:

rd4eva

Erfahrenes Mitglied
Ah jetzt ja so langsam blicke ich ein wenig durch.

C#:
DataRow[] diff2 = haupt_DT.AsEnumerable()
                                                .Where(x =>
                                                        temp_DT.Select("id = " + x["id"])
                                                                .Length == 0
                                                        ).ToArray();

Das nimmt keinerlei Änderungen an haupt_DT oder temp_DT vor.
Das gibt dir nur ein DataRow Array zurück mit Zeilen die in haupt_DT vorhanden und in temp_DT nicht vorhanden sind.
Das hinzufügen zu temp_DT musst du noch selbst erledigen. (z.B. per temp_DT.Rows.Add())
 

Gotenks

Mitglied
(z.B. per temp_DT.Rows.Add())

wenn ich das so mache, bekomme cih den fehler:
Eingabearray ist länger als die Anzahl der Spalten in Tabelle..

Doch verstehen tue ich das nicht da die selben Spalten in haupt_DT vorhanden sind (habe es nämlich ganz schnell mit copy-paste gemacht) verstehe nciht wie so ein fehler zu stande kommt****?

Mfg
 

rd4eva

Erfahrenes Mitglied
Wenn du der Add Methode einfach das DataRow Array übergibst dann verwendet er die überladene Methode und denkt jede einzelne Datarow ist ein Feld.
Klinkt komplizierter als es ist. Aber um dich nicht weiter zu verwirren mach es so :
C#:
for (int i = diff2.Length - 1; i >= 0; i--)
	temp_DT.Rows.Add(diff2[i].ItemArray);
Oder noch besser so:
C#:
for (int i = diff2.Length - 1; i >= 0; i--)
	temp_DT.ImportRow(diff2[i]);