Autor Beitrag
Vegeto
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Fr 31.08.12 11:30 
Hallo @ All

bin schon seit 3 tagen auf der Suche, doch finde nichts zu diesem Thema :/ :cry: :cry:
Ích habe ein DT A (DataTable A) und ein DT B (DataTable B), ich möchte das eine schleifenkonstruktor mit if-anweisung.
Die Datensätze (Rows/Zeilen) von DT A durch geht und wenn in DT B die ID fehlt die es in DT A gibt soll er sie in DT B schreiben und speichern.

DT A dient als Haupt_Datatable, weil dieser Ständig mit der DB kommuniziert. (Hier wird ein andere Kollege von mir neue Datensätze in die SQL Datenbank schreiben, somit wird die DT A immer aktuell sein)
DT B soll als Temp_Datatable dienen, dieses DT ist noch LEER, doch mit dem Konstruktor den ich will, soll er in dieses DT B schreiben und die neuen Datensätze auch gleichzeitig in das DT speichern. So kann ich obwohl in DT A schon neue Datensätze eingefügt sind immer noch die alten Datensätze in ein dataGridView anzeigen.

Dieser Konstruktor/Anweisung soll erst bei einem Button-Klick durchgearbeitet werden.

So stell ich mir das vor, aber es geht nicht:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
if (DT_A.Columns["ID"] != DT_B.Columuns["ID"])
foreach (var row in DT_A.Rows)
{
    DT_B.Rows.Add(row);
}


Doch so funktoniert das nicht :(
Und ich weiß auch nicht wie ich das festhalten soll, dass er die Datensätze in DT B speichert?

lg


Moderiert von user profile iconTh69: Topic aus WinForms verschoben am Fr 31.08.2012 um 12:08
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 31.08.12 11:53 
DataTable hat eine Merge Methode die soweit ich deine Frage verstehe bereits das tut was du versuchst nach zu programmieren.

Für diesen Beitrag haben gedankt: Vegeto
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Fr 31.08.12 12:50 
Hey...

Danke für die schnelle Antwort, habe erst einmal bei MSDN einiges zur Merge-Methode gelesen, doch ich finde nicht, dass diese Methode mein Konstruktor entspricht...

Also als ich den text gelesehen hab, dachte ich jap das ist es :)...Doch dann habe ich weiter gelesehen und mir den Code angeguckt und ich bin der meinung, dass das eine Zusammenfühung frt DataTables ist und kein Vergleich und abspeichern..oder habe ich was falsch verstanden???

Zudem sollen die DT's keine Primary Key spalte besitzen, denn DT A bezieht doch die Datensätze aus der DB und da gibt es schon eine PR-Spalte.

lg
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 31.08.12 13:03 
Wenn deine Datenbank einen Primary Key hat ist das auch der Primary Key in der DataTable.

Der übliche Vorgang ist in einer DataTable ein Sicht auf eine Datenmenge der DB zu haben die irgendeinen alten Zustand darstellt. Später kann man dann die gleiche Abfrage (über zum Beispiel gleichen TableAdapter) in eine andere DataTable ausführen und dann die alte Ergebnis mit dem neuen Ergebnis mergen damit einem der aktuelle Bearbeitungszustand der DataTable nicht verloren geht. Dann kann man danach einfach diese gemergte DataTable wieder in die Datenbank zurückspeichern (zum Beispiel wieder via dem TAbleadapter über denn man auch die Daten geholt hat).

Vielleicht solltest du nochmal genauer ausholen was du anderes brauchst. Zum Beispiel habe ich keine Ahnung was ein Schleifenkonstruktor sein soll. In deiner gezeigten Schleife versuchst du scheinbar DataRow Objekte von einer DataTable in eine andere zu kopieren. Da du aber nix kopierst sondern nur zuweist knallt es da eine DataRow immer nur zu einer DataTable gehören kann.

Für diesen Beitrag haben gedankt: Vegeto
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Fr 31.08.12 13:30 
Also mein problem:
Das Wort "Schleifenkonstruktor " habe ich mir selbst ausgedacht :oops: damit es verständlicher wird, was ich suche.

Ich habe ein DataTable, dass mittels LINQ to DataSet gejoint wurde, hier werden alle Datensätze aus der DB angezeigt die KEINE Null-Values haben ( da es sich um eine Innerjoin handelt), sprich jede Zeile,Spalte und Zelle hat einen Wert. Dieses DataTable ist mein haupt_DT, weil dieser bei jeden Win-Forms start neue Datensätze aus der Datenbank holt und speichert.

Jetzt habe ich noch eine zweite DataTable (temp_DT), die bis jetzt LEER ist. Ich habe ihr schon die selben Spalten wie bei dem haupt_DT hinzugefügt ( auch mit den selben typen).
Nun möchte ich, sobald ich auf Button-Klicke, dass temp_DT einen ABGLEICH/VERGLEICH mit der haupt_DT macht.
Und wenn er feststellt, dass es neue Datensätze gibt die NICHTin temp_DT vorhanden sind, soll er sie von haupt_DT Kopieren und abspeichern.

Ich hoffe du hast jetzt verstanden was ich erreichen will?

Danke schonmal für die ganze bemühungen :)

Lg
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 31.08.12 13:46 
Hallo Vegeto :welcome:

die von Ralf erwähnte Merge-Methode ist genau dafür gedacht. Probiere es einfach mal aus und melde dich dann hier wieder...

Für diesen Beitrag haben gedankt: Vegeto
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Fr 31.08.12 14:46 
Danke zunächst einmal :)

Doch leider verstehe ich das ganze nicht :'(...
Ich habe den ganzen quellcode von MSDN in mein Win Forms Anwendung rein gehauen.
Er macht auch das was die da beschreiben, aber ich weiß nicht wie ich das in mein Programm einfügen soll :(

hier ist mal mein Code:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
DataTable wss_table = result.Tables[0];
DataTable ap_table = result.Tables[1];
DataTable haupt_DT = tables.result_DT(wss_table, ap_table);  
DataTable temp_DT = tables.temp_DT();

        

            haupt_DT.PrimaryKey = new DataColumn[] {haupt_DT.Columns["ID"]};
        

            haupt_DT.RowChanged +=new System.Data.DataRowChangeEventHandler(Row_Changed);

            haupt_DT.AcceptChanges();
            PrintValues(haupt:DT, "Original values");
            //so ab hier komme ich nicht mehr weiter :( und brauch ich diese erstllten methoden von MSDN
            // da alle methoden Console.WriteLine behinhalten und sowas braucht man nicht in WINFORMS.                 

            dataGridView1.DataSource = temp_DT;


Danach wird noch ein DT erstellt, doch dies benötige ich nicht, da ich weiter oben eins erstellt habe. Danch fügen die per hand einfach Rows hinzu, aber ich will ja das er die von haupt_DT nimmt.

Komme echt nicht weiter :/ werde auch von diesen MSDN nie schlaue, werde nur durch dirverse Forenbeiträge schlauer, kommt sicherlich daher da die es etwas verständlicher schreiben...

LG

EDIT
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
            haupt_DT.PrimaryKey = new DataColumn[] {haupt_DT.Columns["ID"]};
        

            haupt_DT.RowChanged +=new System.Data.DataRowChangeEventHandler(Row_Changed);

            haupt_DT.AcceptChanges();
            PrintValues(haupt_DT, "Original values");

            temp_DT = haupt_DT.Clone();   

            haupt_DT.Merge(temp_DT);
            PrintValues(haupt_DT, "Merged With table1");             


            dataGridView1.DataSource = temp_DT;


wenn ich das so mache bekomme ich im datagridview ein leere tabelle
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 31.08.12 16:26 
Hallo nochmals,

m.E. müßte einfach
ausblenden C#-Quelltext
1:
temp_DT.Merge(haupt_DT); // temp_DT ist die Tabelle, auf die kopiert werden soll					

reichen.
Nur wenn bisher kein PrimaryKey vergeben wurde, müßtest du diesen noch explizit angeben (d.h. deine ID-Spalte).

Für diesen Beitrag haben gedankt: Vegeto
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mo 03.09.12 08:11 
Hallo...

Danke werde ich sofort ausprobieren und gleich berichten, konnte über das WE nicht antworten, war für zwei tage weg, bischen erholen :D...Weg vom Arbeitsstress :D hehe

Ich melde mich dann gleich und vergebe auch der spalte ID einfach ein primary key :D
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mo 03.09.12 08:33 
Zitat:
DataColumn[] primArray = new DataColumn[1];
primArray[0] = haupt_DT.Columns["ID"];
haupt_DT.PrimaryKey = primArray;

temp_DT.Merge(haupt_DT);

muss ich auch der temp_DT ein primaryKey vergeben?

Wenn ich das so machen, zeigt er es im DataGridView an :D :D :D *juhu*

Sind dann auch schon die Datensätze von haupt_DT nun auch in temp_DT GESPEICHERT...?
--Also kann ich temp_DT als eigenständige DataTable sehen, der erst nach einem Buttonklick, diese Merge-Methode aufruft und erst dann aktualisiert wird?

DANKE !!!
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 03.09.12 09:29 
Hallo Vegeto,

kurz und knapp: ja, die beiden DataTables sind völlig unabhängig voneinander und erst durch den expliziten Merge werden die Daten abgeglichen und kopiert (und auch danach bleiben die DataTables unabhängig voneinander).

Für diesen Beitrag haben gedankt: Vegeto
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mo 03.09.12 10:21 
Danke ^^

Schau dir bitte mal mein Code an:
Zitat:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
        private void Form1_Load(object sender, EventArgs e)
        {
            DataTable temp_DT = tables.temp_DT();

            dataGridView1.DataSource = temp_DT;  
        }
        private void button3_Click(object sender, EventArgs e)
        {
            DataTable wss_table = result.Tables[0];
            DataTable ap_table = result.Tables[1];
            DataTable haupt_DT = tables.result_DT(wss_table, ap_table);
            DataTable temp_DT = tables.temp_DT();

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

            temp_DT.Merge(haupt_DT) 

            dataGridView1.DataSource = temp_DT;
        }


Wenn ich das so mache dann starte ich WinForms und das Datagridview ist leer, weil temp_DT noch nicht gefüllt ist, sobald ich auf "button3_Click" klicke macht er das so wie ich das will...(Danke nochmal bis hier hin :D )
Doch wenn ich die WinForms schließe und wieder öffne soll er mir die "gefüllte" temp_DT anzeigen, doch dies tut er nicht denn die temp_DT ist wieder leer(und somit auch das dataGridView). ?

Wie schaffe ich das das er beim nächsten start die datensätze anzeig die ich nach dem button klickt erstellt habe.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 03.09.12 13:40 
Dass die Werte in der DataTable nach einen Neustart des Programm weg sind, ist ja wohl klar. Du mußt sie halt irgendwo speichern, entweder in einer Datenbank oder aber z.B. als XML-Datei mittels WriteXml (und beim Programmstart entsprechend z.B. mit ReadXml wieder auslesen).

Für diesen Beitrag haben gedankt: Vegeto
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Mo 03.09.12 15:15 
Okay DANKE VIELMALS...

Kannst du mir vielleicht wenn du zeit hast ein code-snippet zeigen, bis dahin lese ich die doku etc.

DANKE vielmals.
Vegeto Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 262



BeitragVerfasst: Di 04.09.12 15:09 
jetzt habe ich noch eine kleine frage, habe das mit write und read xml hin bekommen. sieht auch super aus

doch wenn ich die merge methode benutze füllt er das datagridview mit daten aus der temp_DT das ist auch gut so :)
Doch wenn ich nochmal auf button klicke lädt er die tabelle neu, das heißt er kopiert wieder alle datensätze aus Haupt_DT in temp_DT rein, wobei sie doch schon einmal mit merge kopiert wurde ??? Wieso macht er es denn nochmal -.-
Wollte es halt mit try-catch festhalten sodass eine messagebox auf srpingt wenn keine neuen daten da sind...

hier mein code:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
        
            DataTable haupt_DT = tables.result_DT(a_table, b_table);
            DataTable temp_DT = tables.temp_DT();
            temp_DT.ReadXml("datatable.xml");

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

            DataColumn[] primArray2 = new DataColumn[1];
            primArray2[0] = temp_DT.Columns["ID"];
            temp_DT.PrimaryKey = primArray2; 

            try
            {
                temp_DT.Merge(haupt_DT);

            }
            catch (Exception)
            {

                MessageBox.Show("Fehler""Nichts Neues");
            }

           
            dataGridView1.DataSource = temp_DT;

            temp_DT.TableName = "temp_DT";

            temp_DT.WriteXml("datatable.xml", XmlWriteMode.WriteSchema);


weiß jemand wo das problem ist?

lg