Announcement

Collapse
No announcement yet.

Problem mit SqlDataAdapter.Update

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem mit SqlDataAdapter.Update

    Hallo zusammen,

    ich habe ein DataSet, das wie folgt geladen wird :

    Code:
    String CommandString = "SELECT processTypes, packageIds, processIds FROM dbo.CUSTOM_processRelation ";
    SqlConnection conn = new SqlConnection(this.myConnString);
    this.adapter = new SqlDataAdapter(CommandString, conn);
    this.myRelationDS = new DataSet("RelationDataSet");
    adapter.Fill(this.myRelationDS, "Relation");
    mySqlCommandBuilder = new SqlCommandBuilder(adapter);
    table = this.myRelationDS.Tables["Relation"];
    Dann möchte ich eine Zeile in der einzigen Tabelle im Dataset ändern, und mache das so :

    Code:
    String[] values = new String[3];
    values[0] = entry;
    values[1] = selectedWorkflowPackage;
    values[2] = selectedWorkflowProcess;
    table.LoadDataRow(values, true);
    Der String "entry" ist der einzige, der noch den alten original-Wert der zu änderenden Zeile enthält, die beiden anderen Werte sind neu, und sollen eben in der Zeile aktualisiert werden.

    Das ganze klappt auch, die Änderungen im DataSet kann ich mir in meiner Gui anschauen.

    Was aber nicht klappt, ist das Speichern der Änderungen am DataSet in die Datenbank, was ich wie folgt mache :

    Code:
    this.adapter.Update(this.myRelationDS,"Relation");
    Ich bekomme aber auch keine Fehlermeldung, es passiert einfach nichts, es wird keine Änderung des DataSets zurückgeschrieben.

    Hier noch die Deklarationen im Konstruktor, der Vollständigkeit halber :
    Code:
     String myConnString = String.Empty;                                         // ConnectionString
    DataSet myRelationDS = null;                                                // DataSet für ProzessZuweisungen
    SqlDataAdapter adapter = null;
    SqlCommandBuilder mySqlCommandBuilder;
    DataTable table;
    Kann mir jemand bitte einen Tipp geben, was ich falsch mache?

    Vielen Dank!

    Beste Grüsse,

    Stefan

  • #2
    Hallo Stefan,

    prüfe Folgendes:
    1. Hat die Tabelle einen PrimaryKey?
    2. Wird dieser Wert geändert?
    3. Steht unter adapter.UpdateCommand nach dem CommandBuilder ein passender Befehl?
    4. Sind die Parameter für diesen Befehl richtig gesetzt worden?

    Der SqlCommandBuilder soll die Befehle bereits durch den Konstruktor erstellen (ich arbeite nicht mit MS-SQL).

    Weitere Hinweise findest Du durch Beiträge von Andreas Kosch.

    Viel Erfolg! Jürgen

    PS. Zum DbCommandBuilder hat Andreas Kosch eine eindeutige Meinung.

    Comment


    • #3
      Hallo Jürgen,

      vielen Dank für deine Antwort.

      Zu 1. Ja, sie hat einen
      Zu 2. Ja, der Wert wird nicht geändert
      Zu 3. und 4.

      Nein, bisher hatte ich hier ja kein eigenes UpdateCommand festgelegt, weil ich ja gelesen hatte, das der SqlCommandBuilder das für mich macht.

      Ich habe jetzt probiert, meinen eigenen UpdateCommand einzubauen, leider führt das zum selben Ergebnis, nix passiert, aber auch keine Fehlermeldung.

      Hier der Code für meinen UpdateCommand :

      Code:
      String CommandString = "SELECT processTypes, packageIds, processIds FROM dbo.CUSTOM_processRelation ";
                  SqlConnection conn = new SqlConnection(this.myConnString);
                  this.adapter = new SqlDataAdapter(CommandString, conn);
                  this.myRelationDS = new DataSet("RelationDataSet");
                  adapter.Fill(this.myRelationDS, "Relation");
                  command = new SqlCommand(
                      "UPDATE dbo.CUSTOM_processRelation SET packageIds = @packageIds, processIds = @processIds " +
                      "WHERE processTypes = @processTypes", conn);
                  command.Parameters.Add("@packageIds", SqlDbType.NVarChar, 50, "packageIds");
                  command.Parameters.Add("@processIds", SqlDbType.NVarChar, 50, "processIds");
                  command.Parameters.Add("@processTypes", SqlDbType.NVarChar, 50, "processTypes");
                  adapter.UpdateCommand = command;
                  table = this.myRelationDS.Tables["Relation"];

      Leider wird mir aus der MSDN sowie aus dem Netz noch nicht ersichtlich, wie das genau mit den Parametern funkioniert, also woher der Adapter nachher weiss, welche Werte er bei welchen Parametern einfügen soll, daher will ich nich ausschliessen, das ich hier was falsch gemacht habe..

      Comment


      • #4
        Code:
        table.LoadDataRow(values, false);
        Du mußt LoadDataRow mit false aufrufen.

        True bedeutet das direkt AcceptChanges aufgerufen wird. Damit gilt dein gerade geänderter/hinzugefügter Satz nicht mehr als modified und wird natürlich nicht upgedatet.

        Comment


        • #5
          Hallo Ralf,

          danke für die Antwort.

          Leider klappt das nicht. Wenn ich das mache, kriege ich beim Aufrufen der Update Anweisung eine InvalidOperationException, und er möchte von mir gerne eine gültige InsertAnweisung haben, weil er meint, das Zeilen hinzugekommen sind. Ich will aber keine Zeilen dazu kriegen, und solange ich wie vorher mit false bei LoadDataRow arbeite, wird meinem Table auch nichts hinzugefügt, es wird nur geändert.

          Nur leider lässt sich der geänderte Table immer noch nicht wieder in die Datenbank speichern..


          Originally posted by Ralf Jansen View Post
          Code:
          table.LoadDataRow(values, false);
          Du mußt LoadDataRow mit false aufrufen.

          True bedeutet das direkt AcceptChanges aufgerufen wird. Damit gilt dein gerade geänderter/hinzugefügter Satz nicht mehr als modified und wird natürlich nicht upgedatet.

          Comment


          • #6
            Hallo Stefan,

            prüfe doch bitte einmal, wenn Du die Änderungen im Debugger erkennen kannst, welchen Rowstate die betroffene Zeile besitzt. Die Fehlermeldung mit hinzugekommenen Zeilen deutet darauf hin, dass etwas mit dem Primärschlüssel etwas nicht stimmt bzw. die entsprechende Zeile nicht gefunden wird (vielleicht doch ein neuer Wert?). In der Hilfe steht:
            "Sucht eine bestimmte Zeile und aktualisiert diese. Wenn keine übereinstimmende Zeile gefunden werden kann, wird eine neue Zeile mit den angegebenen Werten erstellt.....Die LoadDataRow-Methode nimmt ein Array von Werten an und sucht einen oder mehrere übereinstimmende Werte in der bzw. den Primärschlüsselspalten."
            Na ja, nun hast Du eine neue Zeile...

            Gruß
            Olaf

            Comment


            • #7
              Olaf hat Recht.
              Du musst der Datatable mitteilen welche Column der Primary Key ist.

              Code:
              table.PrimaryKey = dt.Columns["processTypes"];

              Comment


              • #8
                Super, das hat geklappt! Vielen 1000 Dank!

                Comment

                Working...
                X