Laden...

Speichern von Änderungen in Datenbank ghet nicht: SqlDataAdapter, Commandbuilder

Erstellt von schuppsl vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.757 Views
S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren
Speichern von Änderungen in Datenbank ghet nicht: SqlDataAdapter, Commandbuilder

Hallo.
entweder bin ich heute schon total neben der Kapp oder ich bin Urlaubsreif:

Ich binde eine DataTable an eine DataGridViewSource:



   con = new SqlConnection(Properties.Settings.Default.MietkleidungConnectionString);
            string befehl = "SELECT mt.ID, mt.PersonalID, mt.Menge, mt.KleidungsID, mt.Schluesselnummer, mt.Groesse FROM miete mt";
            adapMiete = new SqlDataAdapter(befehl, con);
            
            datatMiete = new DataTable("Verwaltung");
           datatMiete.Locale = System.Globalization.CultureInfo.InvariantCulture;
            adapMiete.Fill(datatMiete);
[B]            cmbl = new SqlCommandBuilder(adapMiete);            [/B]
            dataGridViewMiete.DataSource = datatMiete;
           
            datatMiete.PrimaryKey =  new DataColumn[]{datatMiete.Columns["ID"]};


Funktioniert soweit und die Daten werden im DataGridView angezeigt.
Auch der Insert funktioniert, das mache ich über das CellValueChanges Event:



DataRow row = datatMiete.NewRow();
                row[0] = ++x;
                row[1] = dataGridViewMiete.Rows[e.RowIndex].Cells[1].Value.ToString() == "" ? 2 : Convert.ToInt32(dataGridViewMiete.Rows[e.RowIndex].Cells[1].Value);
                row[2] = dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value.ToString() == "" || dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value == DBNull.Value ? 0 : Convert.ToInt16(dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value);
                row[3] = dataGridViewMiete.Rows[e.RowIndex].Cells[3].Value.ToString() == "" ? 22 : Convert.ToInt16(dataGridViewMiete.Rows[e.RowIndex].Cells[3].Value);
                row[4] = dataGridViewMiete.Rows[e.RowIndex].Cells[4].Value.ToString() == "" ? "112233" : dataGridViewMiete.Rows[e.RowIndex].Cells[4].Value.ToString();
                row[5] = dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value.ToString() == "" || dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value == DBNull.Value ? "0" : dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value.ToString(); ;
[B]
datatMiete.Rows.Add(row);
 adapMiete.Update(datatMiete);[/B]




Geht soweit.
Im selben event möchte ich nun Änderungen speichern:


\*Haltepunkt
DataRow row = datatMiete.Rows[e.RowIndex];
                datatMiete.Rows[e.RowIndex][0] = x;
                datatMiete.Rows[e.RowIndex][1] = dataGridViewMiete.Rows[e.RowIndex].Cells[1].Value.ToString();// == "" ? 2 : Convert.ToInt32(dataGridViewMiete.Rows[e.RowIndex].Cells[1].Value);
                datatMiete.Rows[e.RowIndex][2] = dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value.ToString();// == "" || dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value == DBNull.Value ? 0 : Convert.ToInt16(dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value);
                datatMiete.Rows[e.RowIndex][3] = dataGridViewMiete.Rows[e.RowIndex].Cells[3].Value.ToString();// == "" ? 22 : Convert.ToInt16(dataGridViewMiete.Rows[e.RowIndex].Cells[3].Value);
                datatMiete.Rows[e.RowIndex][4] = dataGridViewMiete.Rows[e.RowIndex].Cells[4].Value.ToString();// == "" ? "112233" : dataGridViewMiete.Rows[e.RowIndex].Cells[4].Value.ToString();
                datatMiete.Rows[e.RowIndex][5] = dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value.ToString();// == "" || dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value == DBNull.Value ? "0" : dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value.ToString(); ;
                //      MessageBox.Show(adapMiete.UpdateCommand.CommandText);

           //     DataRowState state = row.RowState;
             //   DataTable getch = datatMiete.GetChanges();
                adapMiete.Update(datatMiete);



Also ich schnappe mir den RowIndex und speichere die Änderungen im Datatable.
Das Problem hierbei ist nun, dass der RowState immer auch "unchanged" steht bzw. GetChanges = null ist.

Die Tabelle hat 6 Spalten. Ändere ich die Dritte, kann ich mir das ja anschauen im Debugger.

Haltepunkt ist auf der ersten Zeile, hier schaue ich nun in die DataTable den einen Wert an.
An dieser Stelle ist dieser aber schon eingetragen, obwohl ich die Zuweisungen noch gar nicht durchlaufen habe.
Daher ist RowState auch immer unchanged.
Doch woher kommt das? Warum ist in der DataTable der geänderte Wert schon aktualisiert, obwohl ich den erst hier zuweise?

2.298 Beiträge seit 2010
vor 8 Jahren

Hallo,

die erste Frage die sich mir stellt: Warum arbeitest du nicht direkt mit DataBinding? Du kannst die ganze DataTable als DataSource an das DataGridView hängen.

Dann würden die DataRows aus der Table sicher auch direkt in den "Dirty"-Modus gehen, wenn du Änderungen innerhalb einer Zeile durchführst.

Ich habe es auch gerade mal grob getestet. Wenn ich deinen Code richtig interpretiere, hast du ja auch bereits die DataTable an das Grid gebunden. Das heißt, die Änderungen gehen Zwangsläufig in das DataTable, wenn du diese vornimmst.

Normalerweise sollte der RowState der DataTable dann auch "Modified" sein. Rufst du vor dem Update-Aufruf AcceptChanges auf?

Würdest du der MSDN folgen, wüsstest du auch, dass dein Hinzufügen / Ändern viel zu viel ist...

Folgendes kleines Beispiel:


DataTable _myData;
SqlDataAdapter _dataAdapter;

private void GetData()
{
     // ... Connection und command initialisieren
    _dataAdapter.Fill(_myData);

    // ... commandbuilder gedöns...

   myData.PrimaryKey =  new DataColumn[]{myData.Columns["ID"]};
   this.MyDataGridView.DataSource = _myData;
}

private void SaveChanges()
{
    _dataAdapter.Update(_myData);
}


Wenn ich mich nicht täusche müsste das voll und ganz ausreichen.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Habe ich gerade versucht, bringt leider nichts...

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Ja leider wird trotzdem nichts zurückgeschrieben...auch wenn ich es ganz minimal erstelle wie in deinem Beispiel...

2.298 Beiträge seit 2010
vor 8 Jahren

Wird denn wie in meinem Beispiel gezeigt, wenigstens der Insert durchgeführt? Außerdem würde ich von "On-The-Fly" Speichern absehen und das nur auf Anforderung machen (Speichern klicken oder ähnliches).

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Ja, der Insert funktioniert.

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Guten Morgen.

Also ich mache das ganze Prozedere ja im Event CellValueChanged.
Liegt es vielleicht daran?

Irgendwie muss ich ja feststellen, ob eine Zeile oder Zelle geändert wurde und dieses abfangen und in die DB schreiben. Per Button möchte ich das nicht machen, sondern direkt bei Änderung bzw. neuer Zeile.
Habe schon etliche Events ausprobiert und das erscheint mir als das sinnvollste.
Kann es daran liegen?

EDIT: Also nach diesem Beispiel geht es, einfacher geht es nicht mehr.

Allerdings muss man dafür einen Button drücken, was oft vergessen wird. Daher hätte ich das gerne in einem Event. Welches wäre hier am sinnvollsten?

2.298 Beiträge seit 2010
vor 8 Jahren

Naja,

dann müsste es analog der Variante mit dem Button-Click auch im CellValueChanged-Event funktionieren. Aus meiner Sicht sollte das gehen, da ja das Verhalten nicht anders ist.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

S
schuppsl Themenstarter:in
789 Beiträge seit 2007
vor 8 Jahren

Analog zu dem verlinkten Beispiel geht es auch nicht in diesem Event... scheint also definitiv das falsche zu sein.

2.298 Beiträge seit 2010
vor 8 Jahren

Probier das ganze mal im "RowValidated"-Event.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

F
10.010 Beiträge seit 2004
vor 8 Jahren

Naja CellValueChanged bedeutet nicht das der Wert final ins DataSet geschrieben wurde.
Du musst dann schon noch ein endedit machen, damit der Wert in der DataTabloe ankommt.

Aber allgemein ist das die falsche herangehensweise. Wenn jemand schnell schreibt und nach jedem zeichen der Datensatz in die DB geschrieben wird, dann macht das nur probleme.