Hallo Liebe Community.
Ich habe ein bestehendes DataGrid indem es ca. 30 Vorprogrammierte Zeilen gibt. Nicht alle spalten sind aber mit Werten gefüllt bzw. stehen auf "0". Der Anwender selbst soll dann die Werte einpflegen. Mit einem Click auf einem Button oder auch mit dem Event SelectionChanged sollen die eingetragenen Werte in die Datenbank gespeichert werden.
Zuvor hatte ich um komplett neue Zeilen in die Datenbank zu schreiben den Befehl TableAdapter.Update(dataset1.TabellenName) benutzt. Dieses funktioniert auch so wie ich es gerne hätte auch wenn es nicht die beste Lösung sein wird.
Sobald aber etwas in einer Zeile "geändert" wird da streikt der Befehl.
Fehler: Für ein Update ist ein gültiger UpdateCommand erforderlich, wenn eine DataRow-Auflistung mit modifizierten Zeilen weitergegeben wird.
Ich habe zwar herausgefunden das man evtl. mit einem DataTable arbeiten könnte. Nur fand ich den Ansatz jetzt nicht prickelnt.
Und die Werte einzeln auslesen und dann in die Datenbank speichern ist wohl zu aufwendig. Es müsste doch einen einfacheren Weg geben.
Meine Frage in dem Sinne ist: Kann man mit einem Befehl die geänderten Werte im DataGrid in die Datenbank speichern?
Zum Verständins mein aktueller Stand:
public partial class Page1 : Page
{
// Variable DataSet
CLR.DataSet1 dataSet1;
// Variablen für Tabelle1
CLR.DataSet1TableAdapters.Tabelle1TableAdapter dataSet1Tabelle1TableAdapter;
System.Windows.Data.CollectionViewSource tabelle1ViewSource;
private void Page_Loaded(object sender, RoutedEventArgs e)
{
// Lädt DataSet
dataSet1 = ((CLR.DataSet1)(this.FindResource("dataSet1";)));
// Lädt Daten aus Tabelle "Tabelle1".
dataSet1Tabelle1TableAdapter = new CLR.DataSet1TableAdapters.Tabelle1TableAdapter();
dataSet1Tabelle1TableAdapter.Fill(dataSet1.Tabelle1);
tabelle1ViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("tabelle1ViewSource";)));
tabelle1ViewSource.View.MoveCurrentToFirst();
}
public void Speichern_Click(object sender, RoutedEventArgs e)
{
dataSet1Tabelle1TableAdapter.Update(dataSet1.Tabelle1);
}
}
Wie die Fehlermeldung schon sagt: Dein TableAdapter hat kein gültiges UpdateCommand! Das musst Du evtl. mit einem CommandBuilder erst mal erzeugen und dem TableAdapter zuweisen.
Beim Erstellen des DataSets im Designer werden oft die Update- und InsertCommands automatisch miterstellt, wenn man den Select-Befehl erstellt. Aber das klappt nicht bei allen Datenbank-Connectoren. SQLite z.B. erstellt dann nur das Selectcommand - alle anderen muss man über den SQLite-CommandBuilder erstellen und dem TA zuweisen - erst dann kann man z.B. TA.Update(table) aufrufen.
Danke für deine schnelle Antwort. Habe dazu folgendes auf http://msdn.microsoft.com/de-de/library/system.data.sqlclient.sqlcommandbuilder.aspx gefunden
public static DataSet SelectSqlRows(string connectionString,
string queryString, string tableName)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(queryString, connection);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
connection.Open();
DataSet dataSet = new DataSet();
adapter.Fill(dataSet, tableName);
//code to modify data in DataSet here
builder.GetUpdateCommand();
//Without the SqlCommandBuilder this line would fail
adapter.Update(dataSet, tableName);
return dataSet;
}
}
frage ist nur welche werte übergebe ich dann in diesem fall?
string connectionString, string queryString, string tableName
ConnectionString und queryString sind ja schon in deinem TA! D.h. du brauchst eigentlich nur den Part:
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
und später (vor TA.Update(DataSet.Tablename):
TA.UpdateCommand=builder.GetUpdateCommand();
Habe jetzt:
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.UpdateCommand = builder.GetUpdateCommand();
dataSet1Tabelle1TableAdapter.Update(dataSet1.Tabelle1);
Als fehlermeldung kam dann:
Die Eigenschaft 'DataAdapter.SelectCommand' muss initialisiert werden.
Also wäre das doch mit "
adapter.SelectCommand = new SqlCommand(-->queryString, connection<--); " oder vertuhe ich mich da jetzt? habe weitere möglichkeiten Ausprobiert. Zum erfolg bin ich da noch nicht gekommen.
Gruß Cubi
Ich dachte, du hast schon einen TableAdapter, der dir das Dataset füllt? Wenn ja, dann hat genau dieser Adapter doch schon das SelectCommand und die Connection (sonst würde adapter.Fill() nicht gehen!). Und genau diesem Adapter weist du das UpdateCommand zu wie oben beschrieben!
Der CommandBuilder baut aufgrund des vorhandenen SelectCommands die "FolgeCommands" auf! Der Adapter braucht also auf jeden Fall erstmal ein SelectCommand; wenn du ihm das im Code mitgeben willst, musst du es in den queryString schreiben:
queryString="Select * From tablename"
Guten Morgen,
Sorry der letzte Post war unnötig von mir, hätte ich einfach besser aufpassen bzw. lesen sollen.
Soweit so gut jetzt kommt die neue Fehlermeldung: Dynamische SQL-Generierung für den UpdateCommand wird nicht für einen SelectCommand unterstützt, der keine Schlüsselspalteninformationen zurückgibt.
Die Tabelle auf die ich zugreife hat aber einen Primärschlüssel! Woran könnte das liegen?
Gruß
Nein ist er nicht: mein Query sieht wie folgt aus!
queryString="Select * From Tabelle1"
wüsste jetzt aber nicht wie ich das angehen soll das dort der PK enthalten ist. in meinem Buch steht dazu nichts.
Gruß
Wenn du "Select *" machst, ist ein vorhandener PK auch in den Meta Daten vorhanden.
Was also bedeutet das deine Aussage das die Tabelle **einen **PK hat nicht stimmt.
Ich kann dir zu 100% Versichern das die Tabelle einen PK hat.
Im DataSet Desinger etc. ist die ID überall als PK zu erkennen!
Es muss doch an irgendwas anderes liegen auch wenn ich es mir nicht vorstellen kann, da ich bis jetzt auch aus anderen Informationsquellen herauslesen konnte das es wohl am PK liegen muss. Aber der ist da!!! Hab wirklich viele Möglichkeiten probiert aber keine Funktioniert. Das wird kein ruhiges Wochenende für mich geben.
Hier mein Aktueller Code mit folgender Fehlermeldung:
"Dynamische SQL-Generierung für den UpdateCommand wird nicht für einen SelectCommand unterstützt, der keine Schlüsselspalteninformationen zurückgibt."
dataSet1Tabelle1TableAdapter.Adapter.SelectCommand = new OleDbCommand("Select * From Tabelle1", dataSet1Tabelle1TableAdapter.Connection);
OleDbCommandBuilder builder = new OleDbCommandBuilder(dataSet1Tabelle1TableAdapter.Adapter);
dataSet1TabelleTableAdapter.Adapter.UpdateCommand = builder.GetUpdateCommand();
dataSet1Tabelle1TableAdapter.Update(dataSet1.Tabelle1);
Gruß und schonmal schönes Wochenende
Cubi
Hallo,
vielleicht helfen dir diese Links, da sind auch Beispiele dabei:
Update-Methode: http://msdn.microsoft.com/de-de/library/z1z2bkx2.aspx
Binden von Daten: http://msdn.microsoft.com/de-de/library/fbk67b6z.aspx
Gruß,
mfg
Wenn du jetzt noch erzählst was für eine DB du da mit OleDbCommand ansprechen willst, kann man dir evtl eher helfen.
Und nochmal, wenn der Designer und der CommandBuilder nicht erkenne das die Abfrage eine PK beinhaltet, können die kein UpdateCommand erzeugen.
Guten Morgen,
*ich verwende eine Oracle DB!
Ich habe bereits verstanden das wenn kein PK vorhanden ist, dass kein UpdateCommand erzeugt werden kann.
Trotzdem wundert mich das dieser Fehler ausgespuckt wird, da in der Tabelle ein PK vorhanden ist! Das ist minimal verwirrend.
Die frage ist eher warum Du OleDb benutzt.
Jede DB hat so ihre Eigenheiten und manchmal kommt der generische OleDb damit nicht zurecht.
Benutze den/einen Oracle spezifischen und schau ob es dann immer noch zu dem Fehler kommt.