Überprüfen von Daten in Datasets in .NET Framework-Anwendungen

Hinweis

Datasets und verwandte Klassen sind ältere .NET-Technologien aus den frühen 2000er Jahren, die es Anwendungen ermöglichen, mit Daten im Arbeitsspeicher zu arbeiten, während die Anwendungen von der Datenbank getrennt sind. Die Technologien sind besonders nützlich für Anwendungen, die es Benutzern ermöglichen, Daten zu ändern und die Änderungen wieder in der Datenbank zu speichern. Obwohl sich Datasets als sehr erfolgreiche Technologie erwiesen haben, empfehlen wir, dass neue .NET-Anwendungen Entity Framework Core verwenden. Entity Framework bietet eine natürlichere Möglichkeit, mit tabellarischen Daten als Objektmodelle zu arbeiten, und verfügt über eine einfachere Programmierschnittstelle.

Die Überprüfung von Daten ist der Prozess der Bestätigung, dass die in Datenobjekte eingegebenen Werte den Einschränkungen im Schema eines Datasets entsprechen. Der Überprüfungsprozess bestätigt außerdem, dass diese Werte den Regeln folgen, die für Ihre Anwendung eingerichtet wurden. Es empfiehlt sich, Daten vor dem Senden von Aktualisierungen an die zugrunde liegende Datenbank zu überprüfen. Dadurch werden Fehler sowie die potenzielle Anzahl von Roundtrips zwischen einer Anwendung und der Datenbank reduziert.

Sie können sich vergewissern, dass die Daten, die in ein Dataset geschrieben werden, gültig sind, indem Sie Überprüfungen in das Dataset selbst integrieren. Das Dataset kann die Daten unabhängig davon überprüfen, wie die Aktualisierung durchgeführt wird – ob direkt durch Steuerelemente in einem Formular, innerhalb einer Komponente oder auf andere Weise. Da das Dataset Teil Ihrer Anwendung ist (im Gegensatz zum Back-End der Datenbank), ist es ein logischer Ort, um eine anwendungsspezifische Überprüfung zu erstellen.

Am besten fügen Sie die Überprüfung in Ihre Anwendung in der partiellen Klassendatei des Datasets ein. Öffnen Sie in Visual Basic oder Visual C# den DataSet-Designer, und doppelklicken Sie auf die Spalte oder Tabelle, für die Sie eine Überprüfung erstellen möchten. Diese Aktion öffnet die Codedatei, in der Sie einen ColumnChanging- oder RowChanging-Ereignishandler erstellen können.

private static void OnColumnChanging(object sender, DataColumnChangeEventArgs e)
{

}

Überprüfen von Daten

Die Überprüfung innerhalb eines Datasets erfolgt auf folgende Weise:

Mehrere Ereignisse werden vom DataTable-Objekt ausgelöst, wenn eine Änderung in einem Datensatz auftritt:

  • Die Ereignisse ColumnChanging und ColumnChanged werden während und nach jeder Änderung an einer einzelnen Spalte ausgelöst. Das ColumnChanging-Ereignis ist nützlich, wenn Sie Änderungen in bestimmten Spalten überprüfen möchten. Informationen zur vorgeschlagenen Änderung werden als Argument mit dem Ereignis übergeben.
  • Die Ereignisse RowChanging und RowChanged werden während und nach jeder Änderung in einer Zeile ausgelöst. Das RowChanging-Ereignis ist allgemeiner. Es weist darauf hin, dass eine Änderung an einer beliebigen Stelle in der Zeile erfolgt, aber Sie wissen nicht, welche Spalte geändert wurde.

Standardmäßig löst jede Änderung in einer Spalte daher vier Ereignisse aus. Die ersten sind die ColumnChanging- und ColumnChanged-Ereignisse für die bestimmte Spalte, die geändert wird. Als nächstes folgen die Ereignisse RowChanging und RowChanged. Wenn an der Zeile mehrere Änderungen vorgenommen werden, werden die Ereignisse für jede Änderung ausgelöst.

Hinweis

Die BeginEdit-Methode der Datenzeile deaktiviert die Ereignisse RowChanging und RowChanged nach jeder einzelnen Spaltenänderung. In diesem Fall wird das Ereignis erst ausgelöst, wenn die EndEdit-Methode aufgerufen wurde und die Ereignisse RowChanging und RowChanged nur einmal ausgelöst werden. Weitere Informationen finden Sie unter Deaktivieren von Einschränkungen beim Auffüllen von Datasets.

Das von Ihnen ausgewählte Ereignis hängt davon ab, wie präzise die Überprüfung sein soll. Wenn es wichtig ist, dass Sie einen Fehler sofort abfangen, wenn eine Spalte geändert wird, erstellen Sie die Überprüfung mithilfe des ColumnChanging-Ereignisses. Verwenden Sie andernfalls das RowChanging-Ereignis, das dazu führen kann, dass mehrere Fehler gleichzeitig abgefangen werden. Wenn Ihre Daten so strukturiert sind, dass der Wert einer Spalte basierend auf dem Inhalt einer anderen Spalte überprüft wird, führen Sie ihre Überprüfung während des RowChanging-Ereignisses durch.

Wenn Datensätze aktualisiert werden, löst das DataTable-Objekt Ereignisse aus, auf die Sie reagieren können, während und nachdem die Änderungen vorgenommen werden.

Wenn Ihre Anwendung ein typisiertes Dataset verwendet, können Sie stark typisierte Ereignishandler erstellen. Dies fügt vier zusätzliche typisierte Ereignisse hinzu, für die Sie Handler erstellen können: dataTableNameRowChanging, dataTableNameRowChanged, dataTableNameRowDeleting und dataTableNameRowDeleted. Diese typisierten Ereignishandler übergeben ein Argument, das die Spaltennamen Ihrer Tabelle enthält und das Schreiben und Lesen von Code erleichtert.

Datenaktualisierungsereignisse

Ereignis BESCHREIBUNG
ColumnChanging Der Wert in einer Spalte wird geändert. Das Ereignis übergibt die Zeile und Spalte zusammen mit dem vorgeschlagenen neuen Wert an Sie.
ColumnChanged Der Wert in einer Spalte wurde geändert. Das Ereignis übergibt die Zeile und Spalte zusammen mit dem vorgeschlagenen Wert an Sie.
RowChanging Die Änderungen, die an einem DataRow-Objekt vorgenommen wurden, werden nun wieder im Dataset committet. Wenn Sie die BeginEdit-Methode nicht aufgerufen haben, wird das RowChanging-Ereignis für jede Änderung an einer Spalte unmittelbar nach dem Auslösen des ColumnChanging-Ereignisses ausgelöst. Wenn Sie BeginEdit aufgerufen haben, bevor Sie Änderungen vornehmen, wird das RowChanging-Ereignis nur ausgelöst, wenn Sie die EndEdit-Methode aufrufen.

Das Ereignis übergibt Ihnen die Zeile zusammen mit einem Wert, der angibt, welche Art von Aktion (Ändern, Einfügen usw.) durchgeführt wird.
RowChanged Eine Zeile wurde geändert. Das Ereignis übergibt Ihnen die Zeile zusammen mit einem Wert, der angibt, welche Art von Aktion (Ändern, Einfügen usw.) durchgeführt wird.
RowDeleting Eine Zeile wird gelöscht. Das Ereignis übergibt Ihnen die Zeile zusammen mit einem Wert, der angibt, welche Art von Aktion (Löschen) durchgeführt wird.
RowDeleted Eine Zeile wurde gelöscht. Das Ereignis übergibt Ihnen die Zeile zusammen mit einem Wert, der angibt, welche Art von Aktion (Löschen) durchgeführt wird.

Die Ereignisse ColumnChanging, RowChanging und RowDeleting werden während des Aktualisierungsprozesses ausgelöst. Sie können diese Ereignisse verwenden, um Daten zu überprüfen oder andere Arten der Verarbeitung durchzuführen. Da die Aktualisierung während dieser Ereignisse im Gange ist, können Sie sie abbrechen, indem Sie eine Ausnahme auslösen, die verhindert, dass die Aktualisierung abgeschlossen wird.

Die Ereignisse ColumnChanged, RowChanged und RowDeleted sind Benachrichtigungsereignisse, die ausgelöst werden, wenn die Aktualisierung erfolgreich abgeschlossen wurde. Diese Ereignisse sind nützlich, wenn Sie basierend auf einer erfolgreichen Aktualisierung weitere Maßnahmen ergreifen möchten.

Überprüfen von Daten während Spaltenänderungen

Hinweis

Der DataSet-Designer erstellt eine partielle Klasse, in der einem Dataset Überprüfungslogik hinzugefügt werden kann. Das vom Designer generierte Dataset löscht bzw. ändert keinen Code in der partiellen Klasse.

Sie können Daten überprüfen, wenn sich der Wert in einer Datenspalte ändert, indem Sie auf das ColumnChanging-Ereignis reagieren. Wenn dieses Ereignis ausgelöst wird, übergibt es ein Ereignisargument (ProposedValue), das den Wert enthält, der für die aktuelle Spalte vorgeschlagen wird. Basierend auf dem Inhalt von e.ProposedValue haben Sie folgende Möglichkeiten:

  • Den vorgeschlagenen Wert annehmen, indem Sie nichts tun.

  • Den vorgeschlagenen Wert ablehnen, indem Sie innerhalb des Ereignishandlers für Spaltenänderungen den Spaltenfehler festlegen (SetColumnError).

  • Optional können Sie ein ErrorProvider-Steuerelement verwenden, um dem Benutzer eine Fehlermeldung anzuzeigen. Weitere Informationen finden Sie unter ErrorProvider Component (ErrorProvider-Komponente).

Die Überprüfung kann auch während des RowChanging-Ereignisses durchgeführt werden.

Überprüfen von Daten während Zeilenänderungen

Sie können Code schreiben, um sicherzustellen, dass alle zu validierenden Spalten Daten enthalten, die den Anforderungen der Anwendung entsprechen. Legen Sie dazu die Spalte fest, um anzugeben, dass sie einen Fehler enthält, wenn ein vorgeschlagener Wert inakzeptabel ist. In den folgenden Beispielen wird ein Spaltenfehler festgelegt, wenn für die Quantity-Spalte ein Wert von 0 oder weniger gilt. Die Ereignishandler für Zeilenänderungen sollten den folgenden Beispielen entsprechen.

So validieren Sie Daten bei Zeilenänderungen (Visual Basic)

  1. Öffnen Sie das Dataset im DataSet-Designer. Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Erstellen eines Datasets im DataSet-Designer.

  2. Doppelklicken Sie auf die Titelleiste der zu validierenden Tabelle. Durch diese Aktion wird der RowChanging-Ereignishandler der DataTable in der Datei für die partielle Klasse des Datasets automatisch erstellt.

    Tipp

    Doppelklicken Sie links neben den Tabellennamen, um den Ereignishandler für Zeilenänderungen zu erstellen. Wenn Sie auf den Tabellennamen doppelklicken, können Sie ihn bearbeiten.

    Private Sub Order_DetailsDataTable_Order_DetailsRowChanging(
        ByVal sender As System.Object, 
        ByVal e As Order_DetailsRowChangeEvent
      ) Handles Me.Order_DetailsRowChanging
    
        If CType(e.Row.Quantity, Short) <= 0 Then
            e.Row.SetColumnError("Quantity", "Quantity must be greater than 0")
        Else
            e.Row.SetColumnError("Quantity", "")
        End If
    End Sub
    

So validieren Sie Daten bei Zeilenänderungen (C#)

  1. Öffnen Sie das Dataset im DataSet-Designer. Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Erstellen eines Datasets im DataSet-Designer.

  2. Doppelklicken Sie auf die Titelleiste der zu validierenden Tabelle. Durch diese Aktion wird eine Datei für die partielle Klasse der DataTable erstellt.

    Hinweis

    Der DataSet-Designer erstellt nicht automatisch einen Ereignishandler für das RowChanging-Ereignis. Sie müssen eine Methode erstellen, mit der Sie das RowChanging-Ereignis behandeln und Code ausführen können, um das Ereignis mit der Initialisierungsmethode der Tabelle zu verknüpfen.

  3. Kopieren Sie den folgenden Code in die partielle Klasse:

    public override void EndInit()
    {
        base.EndInit();
        Order_DetailsRowChanging += TestRowChangeEvent;
    }
    
    public void TestRowChangeEvent(object sender, Order_DetailsRowChangeEvent e)
    {
        if ((short)e.Row.Quantity <= 0)
        {
            e.Row.SetColumnError("Quantity", "Quantity must be greater than 0");
        }
        else
        {
            e.Row.SetColumnError("Quantity", "");
        }
    }
    

So rufen Sie geänderte Zeilen ab

Jede Zeile in einer Datentabelle verfügt über eine RowState-Eigenschaft, die den aktuellen Zustand dieser Zeile mithilfe der Werte in der DataRowState-Enumeration nachverfolgt. Sie können geänderte Zeilen aus einem Dataset oder einer Datentabelle zurückgeben, indem Sie die GetChanges-Methode eines DataSet oder einer DataTable aufrufen. Sie können überprüfen, ob Änderungen vorhanden sind, bevor Sie GetChanges aufrufen, indem Sie die HasChanges-Methode eines Datasets aufrufen.

Hinweis

Nachdem Sie Änderungen an einem Dataset oder einer Datentabelle (durch Aufrufen der AcceptChanges-Methode) committet haben, gibt die GetChanges-Methode keine Daten zurück. Wenn Ihre Anwendung geänderte Zeilen verarbeiten muss, müssen Sie die Änderungen verarbeiten, bevor Sie die AcceptChanges-Methode aufrufen.

Durch Aufrufen der GetChanges-Methode eines Datasets oder einer Datentabelle wird ein neues Dataset oder eine neue Datentabelle zurückgegeben, die nur Datensätze enthält, die geändert wurden. Wenn Sie bestimmte Datensätze abrufen möchten, z. B. nur neue oder nur geänderte Datensätze, können Sie einen Wert aus der DataRowState-Enumeration als Parameter an die GetChanges-Methode übergeben.

Verwenden Sie die DataRowVersion-Enumeration, um auf die verschiedenen Versionen einer Zeile zuzugreifen (z. B. die ursprünglichen Werte, die sich vor der Verarbeitung in einer Zeile befanden).

So rufen Sie alle geänderten Datensätze aus einem Dataset ab

  • Rufen Sie die GetChanges-Methode eines Datasets auf.

    Im folgenden Beispiel wird ein neues Dataset namens changedRecords erstellt und mit allen geänderten Datensätzen aus einem anderen Dataset namens dataSet1 aufgefüllt.

    DataSet changedRecords = dataSet1.GetChanges();
    

So rufen Sie alle geänderten Datensätze aus einer Datentabelle ab

  • Rufen Sie die GetChanges-Methode einer Datentabelle auf.

    Im folgenden Beispiel wird eine neue Datentabelle namens changedRecordsTable erstellt und mit allen geänderten Datensätzen aus einer anderen Datentabelle namens dataTable1 aufgefüllt.

    DataTable changedRecordsTable = dataTable1.GetChanges();
    

So rufen Sie alle Datensätze ab, die einen bestimmten Zeilenzustand aufweisen

  • Rufen Sie die GetChanges-Methode eines Datasets oder einer Datentabelle auf, und übergeben Sie einen DataRowState-Enumerationswert als Argument.

    Das folgende Beispiel zeigt, wie Sie ein neues Dataset namens addedRecords erstellen und es nur mit Datensätzen auffüllen, die dem dataSet1-Dataset hinzugefügt wurden.

    DataSet addedRecords = dataSet1.GetChanges(DataRowState.Added);
    

    Das folgende Beispiel zeigt, wie alle Datensätze zurückgegeben werden, die der Tabelle Customers kürzlich hinzugefügt wurden:

    private NorthwindDataSet.CustomersDataTable GetNewRecords()
    {
        return (NorthwindDataSet.CustomersDataTable)
            northwindDataSet1.Customers.GetChanges(DataRowState.Added);
    }
    

Zugreifen auf die ursprüngliche Version einer Datenzeile

Wenn an Datenzeilen Änderungen vorgenommen werden, werden im Dataset sowohl die ursprüngliche (Original) als auch die neue (Current) Version der Zeile beibehalten. Vor dem Aufruf der AcceptChanges-Methode kann die Anwendung z. B. auf die verschiedenen (in der DataRowVersion-Enumeration definierten) Versionen eines Datensatzes zugreifen und die Änderungen entsprechend verarbeiten.

Hinweis

Verschiedene Versionen einer Zeile sind nur verfügbar, wenn diese schon bearbeitet, die AcceptChanges-Methode jedoch noch nicht aufgerufen wurde. Nach dem Aufruf der AcceptChanges-Methode sind die ursprüngliche und die aktuelle Version identisch.

Wenn Sie den DataRowVersion-Wert zusammen mit dem Spaltenindex (oder dem Spaltennamen als Zeichenfolge) übergeben, wird der Wert der spezifischen Zeilenversion aus dieser Spalte zurückgegeben. Die geänderte Spalte wird während der Ereignisse ColumnChanging und ColumnChanged identifiziert. Dies ist ein guter Zeitpunkt, um die verschiedenen Zeilenversionen zu Validierungszwecken zu überprüfen. Wenn Sie Einschränkungen jedoch vorübergehend deaktiviert haben, werden diese Ereignisse nicht ausgelöst, sodass die geänderten Spalten programmgesteuert ermittelt werden müssen. Sie können dazu die Columns-Auflistung durchlaufen und die unterschiedlichen DataRowVersion-Werte vergleichen.

So rufen Sie die ursprüngliche Datensatzversion ab

  • Greifen Sie auf den Wert einer Spalte zu, und übergeben Sie die DataRowVersion der Zeile, die zurückgegeben werden soll.

    Das folgende Beispiel veranschaulicht, wie Sie mithilfe eines DataRowVersion-Werts den ursprünglichen Wert eines CompanyName-Felds in einer DataRow abrufen:

    string originalCompanyName;
    originalCompanyName = northwindDataSet1.Customers[0]
        ["CompanyName", DataRowVersion.Original].ToString();
    

Zugreifen auf die aktuelle Version einer Datenzeile

So rufen Sie die aktuelle Datensatzversion ab

  • Greifen Sie auf einen Spaltenwert zu, und fügen Sie dann dem Index einen Parameter hinzu, durch den die zurückzugebende Zeilenversion angegeben wird.

    Im folgenden Beispiel wird veranschaulicht, wie Sie mithilfe eines DataRowVersion-Werts den aktuellen Wert eines CompanyName-Felds in einer DataRow abrufen:

    string currentCompanyName;
    currentCompanyName = northwindDataSet1.Customers[0]
        ["CompanyName", DataRowVersion.Current].ToString();