Freigeben über


Arbeiten mit DataAdapter-Ereignissen

Das ADO.NET-DataAdapter-Objekt stellt drei Ereignisse zur Verfügung, mit denen Sie auf Änderungen reagieren können, die an den Daten der Datenquelle vorgenommen wurden. In der folgenden Tabelle werden die Ereignisse des DataAdapter-Objekts aufgeführt.

Ereignis Beschreibung
RowUpdating Ein Vorgang, mit dem eine Zeile aktualisiert, eingefügt oder gelöscht wird (durch Aufrufen einer der Update-Methoden), wird eingeleitet.
RowUpdated Ein Vorgang, mit dem eine Zeile aktualisiert, eingefügt oder gelöscht wird (durch Aufrufen einer der Update-Methoden), ist abgeschlossen.
FillError Bei einer Fill-Operation ist ein Fehler aufgetreten.

RowUpdating und RowUpdated

Das RowUpdating-Ereignis wird ausgelöst, bevor eine Aktualisierung einer Zeile im DataSet in der Datenquelle verarbeitet wurde. Das RowUpdated-Ereignis wird ausgelöst, nachdem eine Aktualisierung einer Zeile im DataSet in der Datenquelle verarbeitet wurde. Folglich können Sie mit dem RowUpdating-Ereignis das Verhalten von Aktualisierungen ändern, bevor sie vorgenommen werden. Auf diese Weise können Sie zusätzliche Verhaltensmöglichkeiten für Aktualisierungen bereitstellen, einen Verweis auf eine aktualisierte Zeile beibehalten, die aktuelle Aktualisierung abbrechen und für einen Batchprozess zur späteren Verarbeitung planen usw. Das RowUpdated-Ereignis eignet sich, um auf Fehler und Ausnahmen zu reagieren, die bei der Aktualisierung auftreten. Sie können dem DataSet Fehlerinformationen sowie die Wiederholungslogik usw. hinzufügen.

Zu dem RowUpdatingEventArgs-Argument und dem RowUpdatedEventArgs-Argument, die an das RowUpdating-Ereignis und das RowUpdated-Ereignis übergeben werden, gehören u. a.: eine Command-Eigenschaft, die auf das Command-Objekt verweist, das für die Aktualisierung verwendet wird; eine Row-Eigenschaft, mit der auf das DataRow-Objekt verwiesen wird, das die aktualisierten Informationen enthält; eine StatementType-Eigenschaft für die Art der durchgeführten Aktualisierung; die TableMapping, falls zugreffend; die Status-Eigenschaft des Vorgangs.

Mit der Status-Eigenschaft können Sie ermitteln, ob während der Aktualisierung ein Fehler aufgetreten ist und, falls gewünscht, die Aktionen für die aktuellen und die entstandenen Zeilen steuern. Wenn das Ereignis auftritt, entspricht die Status-Eigenschaft entweder Continue oder ErrorsOccurred. Die folgende Tabelle zeigt die Werte, die Sie für die Status-Eigenschaft festlegen können, um folgende Aktionen während der Aktualisierung zu steuern.

Status Beschreibung
Continue Führt den Aktualisierungsvorgang fort.
ErrorsOccurred Bricht den Aktualisierungsvorgang ab und löst eine Ausnahme aus.
SkipCurrentRow Ignoriert die aktuelle Zeile und fährt mit dem Aktualisierungsvorgang fort.
SkipAllRemainingRows Bricht den Aktualisierungsvorgang ab, löst jedoch keine Ausnahme aus.

Wenn Sie für die Status-Eigenschaft den Wert ErrorsOccurred angeben, wird eine Ausnahme ausgelöst. Sie können festlegen, welche Ausnahme ausgelöst wird, indem Sie die entsprechende Ausnahme für die Errors-Eigenschaft angeben. Wenn Sie einen der anderen Werte für die Status-Eigenschaft verwenden, wird keine Ausnahme ausgelöst.

Mit der ContinueUpdateOnError-Eigenschaft können Sie ebenfalls Fehler für aktualisierte Zeilen behandeln. Wenn für DataAdapter.ContinueUpdateOnError der Wert True angegeben wird und die Aktualisierung einer Zeile eine Ausnahme auslöst, wird der Text der Ausnahme in die RowError-Information der entsprechenden Zeile aufgenommen. Die Verarbeitung wird fortgesetzt, ohne eine Ausnahme auszulösen. Auf diese Weise können Sie nach Abschluss der Update-Methode auf Fehler reagieren. Beim RowUpdated-Ereignis verhält es sich hingegen so, dass Sie sofort auf den Fehler reagieren können, wenn er festgestellt wird.

Das folgende Codebeispiel zeigt, wie Ereignishandler hinzugefügt und entfernt werden: Der RowUpdating-Ereignishandler schreibt ein Protokoll aller gelöschten Datensätze mit Timestamp. Der RowUpdated-Ereignishandler fügt der RowError-Eigenschaft der Zeile im DataSet Fehlerinformationen hinzu, unterdrückt die Ausnahme und fährt mit der Verarbeitung fort (spiegelt das Verhalten von ContinueUpdateOnError = True wider).

Dim custDA As SqlDataAdapter = New SqlDataAdapter("SELECT CustomerID, CompanyName FROM Customers", nwindConn)

' Add handlers.
AddHandler custDA.RowUpdating, New SqlRowUpdatingEventHandler(AddressOf OnRowUpdating)
AddHandler custDA.RowUpdated, New SqlRowUpdatedEventHandler(AddressOf OnRowUpdated)

' Set DataAdapter command properties, fill the DataSet, and modify the DataSet.

custDA.Update(custDS, "Customers")

' Remove handlers.
RemoveHandler custDA.RowUpdating, New SqlRowUpdatingEventHandler(AddressOf OnRowUpdating)
RemoveHandler custDA.RowUpdated, New SqlRowUpdatedEventHandler(AddressOf OnRowUpdated)

Private Shared Sub OnRowUpdating(sender As Object, args As SqlRowUpdatingEventArgs)
  If args.StatementType = StatementType.Delete Then
    Dim tw As System.IO.TextWriter = System.IO.File.AppendText("Deletes.log")
    tw.WriteLine("{0}: Customer {1} Deleted.", DateTime.Now, args.Row("CustomerID", DataRowVersion.Original))
    tw.Close()
  End If
End Sub

Private Shared Sub OnRowUpdated(sender As Object, args As SqlRowUpdatedEventArgs)
  If args.Status = UpdateStatus.ErrorsOccurred
    args.Status = UpdateStatus.SkipCurrentRow
    args.Row.RowError = args.Errors.Message
  End If
End Sub
[C#]
SqlDataAdapter custDA = new SqlDataAdapter("SELECT CustomerID, CompanyName FROM Customers", nwindConn);

// Add handlers.
custDA.RowUpdating += new SqlRowUpdatingEventHandler(OnRowUpdating);
custDA.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);

// Set DataAdapter command properties, fill the DataSet, and modify the DataSet.

custDA.Update(custDS, "Customers");

// Remove handlers.
custDA.RowUpdating -= new SqlRowUpdatingEventHandler(OnRowUpdating);
custDA.RowUpdated -= new SqlRowUpdatedEventHandler(OnRowUpdated);

protected static void OnRowUpdating(object sender, SqlRowUpdatingEventArgs args)
{
  if (args.StatementType == StatementType.Delete)
  {
    System.IO.TextWriter tw = System.IO.File.AppendText("Deletes.log");
    tw.WriteLine("{0}: Customer {1} Deleted.", DateTime.Now, args.Row["CustomerID", DataRowVersion.Original]);
    tw.Close();
  }
}

protected static void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
{
  if (args.Status == UpdateStatus.ErrorsOccurred)
  {
    args.Row.RowError = args.Errors.Message;
    args.Status = UpdateStatus.SkipCurrentRow;
  }
}

FillError

Das DataAdapter-Objekt gibt das FillError-Ereignis aus, wenn ein Fehler während einer Fill-Operation auftritt. Dieser Fehlertyp tritt auf, wenn die Daten in der hinzugefügten Zeile nicht ohne Präzisionsverlust in einen .NET Framework-Typ konvertiert werden konnten.

Wenn ein Fehler während einer Fill-Operation auftritt, wird die aktuelle Zeile der DataTable nicht hinzugefügt. Mit dem FillError-Ereignis können Sie den Fehler auflösen und die Zeile hinzufügen oder die betreffende Zeile ignorieren und die Fill-Operation fortsetzen.

Die an das FillError-Ereignis übergebenen FillErrorEventArgs können mehrere Eigenschaften enthalten, mit denen Sie auf Fehler reagieren und sie auflösen können. In der folgenden Tabelle werden die Ereignisse des FillErrorEventArgs-Objekts angezeigt.

Eigenschaft Beschreibung
Errors Die aufgetretene Ausnahme.
DataTable Das DataTable-Objekt, das gefüllt wurde, als der Fehler auftrat.
Values Ein Objektarray, das die Werte der beim Eintreten des Fehlers hinzugefügten Zeile enthält. Die Ordinalverweise des Values-Arrays entsprechen den Ordinalverweisen der Spalten der hinzugefügten Zeile. Values[0] ist beispielsweise der Wert, der als erste Spalte der Zeile hinzugefügt wurde.
Continue Sie können festlegen, ob eine Exception ausgelöst werden soll oder nicht. Wenn Sie für die Continue-Eigenschaft False festlegen, wird die aktuelle Fill-Operation angehalten und eine Ausnahme ausgelöst. Wenn für Continue der Wert True festgelegt wird, wird die Fill-Operation trotz des Fehlers fortgesetzt.

Im folgenden Codebeispiel wird ein Ereignishandler für das FillError-Ereignis des DataAdapter-Objekts hinzugefügt. Für den FillError-Ereigniscode bestimmt das Beispiel, ob Präzisionsverlust möglich ist und ob auf die Ausnahme reagiert werden kann.

AddHandler myDA.FillError, New FillErrorEventHandler(AddressOf FillError)

Dim myDS As DataSet = New DataSet
myDA.Fill(myDS, "MyTable")

Private Shared Sub FillError(sender As Object, args As FillErrorEventArgs)
  If args.Errors.GetType() Is Type.GetType("System.OverflowException") Then
    ' Code to handle precision loss.
    ' Add a row to table using the values from the first two columns.
    DataRow myRow = args.DataTable.Rows.Add(New Object() {args.Values(0), args.Values(1), DBNull.Value})
    ' Set the RowError containing the value for the third column.
    args.RowError = "OverflowException Encountered. Value from data source: " & args.Values(2)

    args.Continue = True
  End If
End Sub
[C#]
myDA.FillError += new FillErrorEventHandler(FillError);

DataSet myDS = new DataSet();
myDA.Fill(myDS, "MyTable");

protected static void FillError(object sender, FillErrorEventArgs args)
{
  if (args.Errors.GetType() == typeof(System.OverflowException))
  {
    // Code to handle precision loss.
    //Add a row to table using the values from the first two columns.
    DataRow myRow = args.DataTable.Rows.Add(new object[] {args.Values[0], args.Values[1], DBNull.Value});
    //Set the RowError containing the value for the third column.
    args.RowError = "OverflowException Encountered. Value from data source: " + args.Values[2];

    args.Continue = true;
  }
}

Siehe auch

Datenzugriff mit .NET Framework-Datenprovidern | SqlRowUpdatedEventArgs-Klasse | SqlRowUpdatingEventArgs-Klasse | OleDbRowUpdatedEventArgs-Klasse | OleDbRowUpdatingEventArgs-Klasse | OdbcRowUpdatedEventArgs-Klasse | OdbcRowUpdatingEventArgs-Klasse | FillErrorEventArgs-Klasse