## 27.4 Neue Autoinkrementwerte abrufen Wenn Sie der Tabelle Products eine neue Datenzeile hinzufügen, wird ein Primärschlüsselwert generiert, der automatisch von der Datenbank erzeugt wird. Nicht alle Datenbanken unterstützen dieses Feature, aber der SQL Server gehört dazu. Das Problem bei der Aktualisierung durch Hinzufügen einer neuen Datenzeile ist, dass der DataRow im DataSet nach der Aktualisierung der von der Datenbank erzeugte Primärschlüssel nicht zur Verfügung steht, während jede andere Aktualisierung dazu führt, dass die DataRowVersion.Original den Wert von DataRowVersion.Current annimmt. Wie also erhalten wir nach dem Hinzufügen den neuen, aktuellen Primärschlüssel einer Autoinkrementspalte? Hier hilft uns der SQL Server mit seiner integrierten Funktion @@IDENTITY. Sie liefert den letzten erzeugten Autoinkrementwert zurück. Wir können das Beispiel aus dem letzten Abschnitt nun in der Weise ergänzen, dass wir für unsere beiden hinzuzufügenden Datenzeilen die entsprechenden Werte im Ereignishandler zu RowUpdated abfragen und der Spalte ProduktID der betreffenden Datenzeile zuordnen.
    static void da_RowUpdated(object sender, SqlRowUpdatedEventArgs e) {
      // Konfliktanalyse
      if (e.Status == UpdateStatus.ErrorsOccurred) {
        ...
      }
      // Abfrage der neuen Autoinkrementwerte
      else if ((e.Status == UpdateStatus.Continue) &&
               (e.StatementType == StatementType.Insert)) {
        SqlCommand cmdPS = new SqlCommand();
        cmdPS.CommandText = "SELECT @ProductID = @@IDENTITY";
        cmdPS.Connection = con;
        SqlParameter param = cmdPS.Parameters.Add("@ProductID", SqlDbType.Int);
        param.Direction = ParameterDirection.Output;
        cmdPS.ExecuteNonQuery();
        e.Row["ProductID"] = cmdPS.Parameters["@ProductID"].Value;
      }
    }
Zunächst muss sichergestellt werden, dass nur die erfolgreiche Aktualisierung einer neu hinzugefügten Datenzeile vom folgenden Code behandelt wird. Die Eigenschaften Status und StatementType des EventsArgs-Objekts gestatten uns eine entsprechende Filterung. Im Anweisungsblock wird zuerst ein SqlCommand-Objekt erzeugt. Der CommandText-Eigenschaft weisen wir mit
    SELECT @ProductID = @@IDENTITY
den Rückgabewert von @@IDENTITY zu. Der Parameter @ProductID muss als Ausgabeparameter festgelegt werden. Nach dem Aufruf der Methode ExecuteNonQuery können wir dem Parameter den neuen Wert entnehmen und ihn in die Spalte ProductID der entsprechenden Datenzeile schreiben. Bevor Sie die Anwendung testen, müssen Sie noch berücksichtigen, dass aufgrund des Aufrufs von FillSchema die Spalte ProductID schreibgeschützt ist. Sie müssen deshalb mit
    ds.Tables[0].Columns["ProductID"].ReadOnly = false;
vor dem Aufruf der Update-Methode des SqlDataAdapters den Schreibschutz wieder aufheben.
Hinweis
Das komplette Beispiel finden Sie auf der Buch-DVD unter: …\Beispiele\Kapitel27\ AutoInkrementSample