Laden...

TableAdapter.Update() Änderungen

Erstellt von Cubi vor 11 Jahren Letzter Beitrag vor 11 Jahren 9.489 Views
C
Cubi Themenstarter:in
16 Beiträge seit 2012
vor 11 Jahren
TableAdapter.Update() Änderungen

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);
}
}

M
28 Beiträge seit 2011
vor 11 Jahren

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.

C
Cubi Themenstarter:in
16 Beiträge seit 2012
vor 11 Jahren

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

M
28 Beiträge seit 2011
vor 11 Jahren

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();

C
Cubi Themenstarter:in
16 Beiträge seit 2012
vor 11 Jahren

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

M
28 Beiträge seit 2011
vor 11 Jahren

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"

C
Cubi Themenstarter:in
16 Beiträge seit 2012
vor 11 Jahren

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ß

F
10.010 Beiträge seit 2004
vor 11 Jahren

Und der PK ist auch in deiner Query enthalten?

C
Cubi Themenstarter:in
16 Beiträge seit 2012
vor 11 Jahren

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ß

F
10.010 Beiträge seit 2004
vor 11 Jahren

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.

C
Cubi Themenstarter:in
16 Beiträge seit 2012
vor 11 Jahren

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

N
54 Beiträge seit 2011
vor 11 Jahren

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

F
10.010 Beiträge seit 2004
vor 11 Jahren

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.

C
Cubi Themenstarter:in
16 Beiträge seit 2012
vor 11 Jahren

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.

F
10.010 Beiträge seit 2004
vor 11 Jahren

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.