Autor Beitrag
Orothred
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Mi 21.11.07 16:10 
Hi!

Ich habe eine Form mit einem DataGrid. In dieses DataGrid lese ich über ein DataSet eine Tabelle aus einer SQL-Datenbank ein.

Jetzt kann ich ja in meinem DataGrid Änderungen an den Daten vornehmen.

Dann will ich den gesamten Inhalt vom DataGrid wieder zurück in die Tabelle der SQL-Datenbank schreiben. Wie mach ich das?
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 21.11.07 16:20 
Genau so, wie du die Daten in das DataSet geholt hast: über einen (typisierten) DataAdapter.
Orothred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Mi 21.11.07 16:25 
also da.Fill(ds) und dann einfach ne sql-connection mit dem dataadpater machen oder wie?
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 21.11.07 17:22 
naja, "Fill" ist zum Füllen da. Vielleicht findest du ja eine etwas passendere Mehode ;) .
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mi 21.11.07 18:19 
Khabarakh's Vorschlag solltest Du Dir zu Herzen nehmen: Öffne die SDK-Doku (die sollte sowieso das wichtigste Hilfsmittel sein - noch wichtiger als alle Foren, in denen Du grundlegende Fragen stellst) zu einem Stichwort - jetzt z.B. DataAdapter - und schau nach, welche Eigenschaften und Methoden angeboten werden.

Für die Grundlagen zur Datenverarbeitung kann ich verweisen auf OpenBook Visual C# Kap.26.

Jürgen
Orothred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Do 29.11.07 09:21 
hm, leider bin ich hier immer noch net weiter gekommen. im moment tue ich folgendes:

ich stelle eine verbindung zum sql-server her.
ich erstelle ein sqlcommand, das ich mit einem select-command fülle, dass alle spalten aus einer tabelle auswählt.
nun erstelle ich einen dataadapter und übergebe ihm das sqlcommand
nun erstelle ich einen sqlcommandbuilder, und übergebe der eigenschaft dataadapter.update-command den wert sqlcommandbuildeer.getupdatecommand.
nun versuche ich mit dataadatper.update mein dataset in die datenbank zu schreiben.

nicht passiert...

ich bin am verzweifeln ^^
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Do 29.11.07 10:49 
user profile iconOrothred hat folgendes geschrieben:

nun versuche ich mit dataadatper.update mein dataset in die datenbank zu schreiben.

nicht passiert...

Das Verfahren als solches klingt vernünftig. Aber sind auch alle "Rahmenbedingungen" erfüllt? Der DbCommandBuilder kann nur arbeiten, wenn der SelectCommand sich auf genau eine Tabelle bezieht (JOINs sind also verboten) und der PrimaryKey im SELECT enthalten ist. DbDataAdapter.Update() wertet den RowState der betroffenen Zeilen aus; sind denn auch wirklich welche geändert worden?

Hinweis für den Debugger: UpdateCommand kontrollieren, RowState kontrollieren, Rückgabewert der Update-Methode prüfen.

Gruß Jürgen
Orothred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Do 29.11.07 10:56 
achso, stimmt, ich bekomme noch die fehlermeldung, das das select-command nicht initialisiert wurde...

was kann ich denn dagegen tun? weil an der tabelle selbst darf ich net rumspielen, die liegt auf den sql-servern von der firma....da hab ich ja nix verloren ^^
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Do 29.11.07 11:04 
Ist doch offensichtlich: Du musst den ursprünglichen Select-Command so ändern, dass er die Bedingungen des DbCommandBuilder erfüllt, und dann dem DbCommandBuilder zuweisen ("initialisieren"). Jürgen
Orothred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Do 29.11.07 11:06 
ich glaub ich bin zu doof dafür ^^

wie weiß ich das dem DBCommandBuilder zu?
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Do 29.11.07 13:09 
Guckst Du in die SDK-Doku, dann verstehe (neben der Anleitung) das Beispiel bei der SqlCommandBuilder-Klasse. Jürgen
Orothred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Do 29.11.07 14:33 
Ok, die Funktionsweise hab ich jetzt verstanden, aber es funktioniert immer noch nicht.

Hier mal mein Code

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
private void btnOK_Click(object sender, EventArgs e)
      {
         SQLHelper sqlhelper = globalCommonData.DefaultDBConnection;
         DbConnection dbConnection = sqlhelper.GetConnection();
         SqlDataAdapter da = new SqlDataAdapter();
         da.SelectCommand = new SqlCommand("SELECT * FROM JITNT.tour_plan");
         SqlCommandBuilder builder = new SqlCommandBuilder(da);
         da.Update(globalDS);
      }


SQLHelper ist eine fertige Klasse aus einem Projekt, das wir hier in der Firma für Datenbankanwendungen benutzen. Sie enthält verschieden Funktionen für den Datenbankzugriff, unter anderem die hier verwendete Funktion GetConnection, mit der eine Verbindung zur Datenbank hergestellt wird. Den Code darf ich auch aber leider nicht zeigen.
So, nun hab ich in der SDK gelesen, dass ich dem CommandBuilder das Connection-Objekt überegeben soll. Der CommandBuilder will aber eine SQLConnection, wir verwenden hier eine DbConnection. Wie krieg ich das Ding jetzt zum Laufen?

Moderiert von user profile iconjasocul: Code- durch C#-Tags ersetzt
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Do 29.11.07 16:04 
Ab hier kann Dir niemand helfen, das musst Du selbst untersuchen, weil Du nur den SQLHelper verwenden kannst. Dazu kannst Du den Debugger verwenden oder Roeder's Reflector.

Das Problem liegt darin, dass alle Sql-Klassen abgeleitet wurden von den entsprechenden Db-Klassen. Wenn sqlhelper.GetConnection() eine SqlConnection liefert, kann diese entsprechend verwendet werden, z.B. mit dem as-Parameter. Aber wenn es sich um eine andere DbConnection handelt, dann führt dies zu Exceptions.

Alternative: Du kannst anstelle der Sql-Klassen selbst ausschließlich Db-Klassen verwenden. Dann bist Du aber beschränkt auf die Minimalfunktionen aller Db-Klassen. Beispiel:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
private void btnOK_Click(object sender, EventArgs e)
      {
         SQLHelper sqlhelper = globalCommonData.DefaultDBConnection;
         DbConnection dbConnection = sqlhelper.GetConnection();
         DbDataAdapter da = new DbDataAdapter();
         da.SelectCommand = new DbCommand("SELECT * FROM JITNT.tour_plan");
         DbCommandBuilder builder = new DbCommandBuilder(da);
         da.Update(globalDS);
      }

Gruß Jürgen
Orothred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Do 29.11.07 17:17 
von den Klassen DbDataAdapter, DbCommand und DbCommandBuilder darf ich keine Instanzen bilden sagt er mir...

so ein sch... da!
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Do 29.11.07 18:30 
Das hatte ich jetzt nicht untersucht. Aber auch dann geht es, allerdings wird es noch (schwieriger) umständlicher:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
//  erzeuge die Verbindung zum DataProvider und zur Datenbank
DbProviderFactory dataFactory 
    = DbProviderFactories.GetFactory("System.Data.SqlClient");
DbConnection conn = dataFactory.CreateConnection();
DbDataAdapter da = dataFactory.CreateDataAdapter();  
DbCommandBuilder bld = dataFactory.CreateCommandBuilder();
//  usw.

So etwas funktioniert wirklich! Die Frage ist, ob Du Dich so sehr in die Details vertiefen willst (zumal Du doch eher Anfänger zu sein scheinst).

Jürgen
Orothred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Mo 03.12.07 08:33 
So sieht mein Code jetzt aus:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
// Instanzen der Db-Klassen erzeugen
         DbProviderFactory dataFactory = DbProviderFactories.GetFactory("System.Data.SqlClient");
         DbConnection dbConnection = dataFactory.CreateConnection();
         DbDataAdapter da = dataFactory.CreateDataAdapter();
         DbCommand cmd = dataFactory.CreateCommand();
         DbCommandBuilder builder = dataFactory.CreateCommandBuilder();
         
         SQLHelper sqlhelper = globalCommonData.DefaultDBConnection;
         dbConnection = sqlhelper.GetConnection();
         cmd.CommandText = "SELECT * FROM JITNT.tour_plan";
         da.SelectCommand = cmd;
         builder.DataAdapter = da;
         da.Update(globalDS);



funktionieren tut das hochladen immer noch nicht....

Moderiert von user profile iconjasocul: Code- durch C#-Tags ersetzt
Orothred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Mo 03.12.07 08:48 
ok, hatte ja noch kein update-command erzeugt.

nachdem ich die da.UpdateCommand eigenschaft mit builder.GetUpdateCommand belegt hatte, bekam ich die fehlermeldung, das die DataAdapter.SelectCommand.Connection-Eigenschaft nicht initialisiert wird.

Also hab ich sie mit dbConnection initialisiert.

Jetzt bekomme ich wieder die Fehlermeldung, das die DataAdapter.SelectCommand-Eigenschaft nicht initialisiert ist. Aber ich initialisiere sie doch...

Hier der aktuelle Code:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
         // Instanzen der Db-Klassen erzeugen
         DbProviderFactory dataFactory = DbProviderFactories.GetFactory("System.Data.SqlClient");
         DbConnection dbConnection = dataFactory.CreateConnection();
         DbDataAdapter da = dataFactory.CreateDataAdapter();
         DbCommand cmd = dataFactory.CreateCommand();
         DbCommandBuilder builder = dataFactory.CreateCommandBuilder();
         
         SQLHelper sqlhelper = globalCommonData.DefaultDBConnection;
         dbConnection = sqlhelper.GetConnection();
         cmd.CommandText = "SELECT * FROM JITNT.tour_plan";
         da.SelectCommand = cmd;
         da.SelectCommand.Connection = dbConnection;
         da.UpdateCommand = builder.GetUpdateCommand();
         da.Update(globalDS);


Moderiert von user profile iconjasocul: Code- durch C#-Tags ersetzt
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mo 03.12.07 10:01 
Hallo,

hast Du auch verstanden, was ich Dir als Weg angeboten habe, oder hast Du es nur kopiert? Dein letzter Code enthält folgende Problemstellen:

Zeile 3: dbConnection wird erzeugt, aber noch ohne Details.
Zeile 4: da wird erzeugt, aber ohne Verbindung mit dbConnection.
Zeile 5, 6: ebenso
Zeile 9: dbConnection wird nochmals erzeugt, und zwar vermutlich mit den Details, die der sqlhelper liefert.

Außerdem kommt es zum Teil auf die Reihenfolge der Zuweisungen an. Das musst Du in den Anleitungen (z.B. OpenBook) oder SDK-Doku nachprüfen. Meine Vermutungen lauten: Zuerst cmd.Connection festlegen, dann cmd dem DbDataAdapter zuweisen. Außerdem weiß ich nicht auswendig, wann der CommandBuilder aktiv wird; vielleicht muss zunächst da.Fill() ausgeführt werden.

Jürgen
Orothred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Mo 03.12.07 10:41 
hm, meiner meinung nach übergebe ich hier

ausblenden C#-Quelltext
1:
dbConnection = sqlhelper.GetConnection();					


die details an dbConnection, erzeugt wird es allerdings nicht nocheinmal, sondern nur mit werten versorgt.

des weiteren wird hier

ausblenden C#-Quelltext
1:
da.SelectCommand.Connection = dbConnection;					


der DataAdapter mit den Werten von dbConnetion versorgt.


daraus würde folgen das der CommandBuilder hier

ausblenden C#-Quelltext
1:
da.UpdateCommand = builder.GetUpdateCommand();					


aktiv wird, mit den Details aus dem DataAdapter.

und hier

ausblenden C#-Quelltext
1:
da.SelectCommand = cmd;					


wird meiner meinung nach das SelectCommand initialisiert. Allerdings behauptet das Programm das gegenteil ^^

Korrigiere mich bitte wenn meine vermutungen falsch sind ^^


und ja, ich hab verstanden, was du mir als weg angeboten hast. hab mich über DbProviderFactory in MSDN informiert und es danach benutzt. NICHT abgeschrieben ^^

Moderiert von user profile iconjasocul: Code- durch C#-Tags ersetzt
Orothred Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 86


C# (VS 2005)
BeitragVerfasst: Mo 03.12.07 12:07 
hab ihn mittlerweile soweit das er ein UPDATE-Command zusammenbaut. hab noch

ausblenden C#-Quelltext
1:
builder.DataAdapter = da;					


eingefügt, dann gings.


das update-command, das er baut, wenn ich eine zeile lösche oder editiere ist immer gleich und lautet:

ausblenden C#-Quelltext
1:
UPDATE [JITNT].[tour_plan] SET[key] = @p1, [ts_start_est] = @p2, [dest_code] = @p3, [status] = @p4, [session_create] = @p5, [lasupdate] = @p6, [user] = @p7, [payload_cars] = @p8 WHERE (([id] = @p9) AND ([key] = @p10) AND ([ts_start_est] = @p11) AND ([dest_code] = p@12) AND ([status] = @p13) AND ([session_create] = @p14) AND ([lastupdate] = @p15) AND ([user] = @p16) AND ([payload_cars) = @p17))					


updaten tut er immer noch nix....

Moderiert von user profile iconjasocul: Code- durch C#-Tags ersetzt