DataTable-Einschränkungen

Mithilfe von Einschränkungen können Sie die in einer DataTable enthaltenen Daten einschränken, um die Datenintegrität zu erhalten. Eine Einschränkung ist eine automatische Regel, die auf eine Spalte oder zugehörige Spalten angewendet wird und die die Vorgehensweise beim Ändern des Werts einer Spalte festlegt. Einschränkungen werden erzwungen, wenn die System.Data.DataSet.EnforceConstraints-Eigenschaft von DataSet auf true festgelegt wird. Ein Codebeispiel, in dem das Festlegen der EnforceConstraints-Eigenschaft veranschaulicht wird, finden Sie im EnforceConstraints-Referenzthema.

Es gibt zwei Arten von Einschränkungen in ADO.NET: die ForeignKeyConstraint und die UniqueConstraint. In der Standardeinstellung werden beide Einschränkungen automatisch erstellt, wenn Sie eine Beziehung zwischen zwei oder mehr Tabellen herstellen, indem Sie dem DataSet ein DataRelation-Element hinzufügen. Dieses Verhalten kann jedoch auch deaktiviert werden, indem beim Erstellen der Beziehung createConstraints = false festgelegt wird.

ForeignKeyConstraint

Mit den durch ForeignKeyConstraint festgelegten Regeln wird bestimmt, wie Updates und Löschvorgänge an zugehörige Tabellen weitergegeben werden. Wenn beispielsweise ein Wert in einer Zeile einer Tabelle aktualisiert oder gelöscht und dieser Wert auch in mindestens einer zugehörigen Tabellen verwendet wird, wird mit ForeignKeyConstraint festgelegt, was in den zugehörigen Tabellen geschieht.

Mithilfe der DeleteRule-Eigenschaft und der UpdateRule-Eigenschaft von ForeignKeyConstraint werden die Aktionen definiert, die beim Versuch des Benutzers bzw. der Benutzerin, eine Zeile in einer zugehörigen Tabelle zu löschen oder zu aktualisieren, ausgeführt werden. In der folgenden Tabelle werden die verschiedenen Einstellungen beschrieben, die für die DeleteRule-Eigenschaft und die UpdateRule-Eigenschaft von ForeignKeyConstraint verfügbar sind.

Festgelegte Regel Beschreibung
Cascade Verknüpfte Zeilen werden gelöscht oder aktualisiert.
SetNull Für die Werte in verknüpften Zeilen wird DBNull festgelegt.
SetDefault Für die Werte in verknüpften Zeilen wird der Standardwert festgelegt.
None In verknüpften Zeilen wird keine Aktion ausgeführt. Dies ist die Standardeinstellung.

ForeignKeyConstraint kann Änderungen an zugehörigen Spalten sowohl einschränken als auch weitergeben. Je nachdem, welche Eigenschaften für ForeignKeyConstraint einer Spalte festgelegt werden und ob die EnforceConstraints-Eigenschaft von DataSet auf true festgelegt wird, löst das Ausführen von bestimmten Vorgängen in der übergeordneten Zeile eine Ausnahme aus. Wenn beispielsweise die DeleteRule-Eigenschaft von ForeignKeyConstraint auf None festgelegt ist, kann eine übergeordnete Zeile nicht gelöscht werden, wenn sie über untergeordnete Zeilen verfügt.

Sie können eine Fremdschlüsseleinschränkung zwischen einzelnen Spalten oder in einem Spaltenarray erstellen, indem Sie den ForeignKeyConstraint-Konstruktor verwenden. Übergeben Sie das resultierende ForeignKeyConstraint-Objekt an die Add-Methode der Constraints-Eigenschaft der Tabelle. Bei dieser handelt es sich um ein ConstraintCollection-Element. Sie können auch Konstruktorargumente an mehrere Überladungen der Add-Methode von ConstraintCollection übergeben, um ForeignKeyConstraint zu erstellen.

Beim Erstellen von ForeignKeyConstraint können Sie den DeleteRule-Wert und den UpdateRule-Wert als Argumente an den Konstruktor übergeben oder als Eigenschaften festlegen. Dies wird im folgenden Beispiel gezeigt, bei dem der DeleteRule-Wert auf None festgelegt wird.

Dim custOrderFK As ForeignKeyConstraint = New ForeignKeyConstraint("CustOrderFK", _  
  custDS.Tables("CustTable").Columns("CustomerID"), _  
  custDS.Tables("OrdersTable").Columns("CustomerID"))  
custOrderFK.DeleteRule = Rule.None
' Cannot delete a customer value that has associated existing orders.  
custDS.Tables("OrdersTable").Constraints.Add(custOrderFK)  
ForeignKeyConstraint custOrderFK = new ForeignKeyConstraint("CustOrderFK",  
  custDS.Tables["CustTable"].Columns["CustomerID"],
  custDS.Tables["OrdersTable"].Columns["CustomerID"]);  
custOrderFK.DeleteRule = Rule.None;
// Cannot delete a customer value that has associated existing orders.  
custDS.Tables["OrdersTable"].Constraints.Add(custOrderFK);  

AcceptRejectRule

Änderungen an Zeilen können mithilfe der AcceptChanges-Methode übernommen oder mit der RejectChanges-Methode von DataSet, DataTable oder DataRow abgebrochen werden. Wenn ForeignKeyConstraints in DataSet enthalten ist, wird durch Aufrufen der AcceptChanges-Methode oder der RejectChanges-Methode AcceptRejectRule erzwungen. Die AcceptRejectRule-Eigenschaft von ForeignKeyConstraint bestimmt, welche Aktion in den untergeordneten Zeilen ausgeführt wird, wenn in der übergeordneten Zeile AcceptChanges oder RejectChanges aufgerufen wird.

In der folgenden Tabelle werden die für AcceptRejectRule verfügbaren Einstellungen aufgeführt.

Festgelegte Regel Beschreibung
Cascade Änderungen in untergeordneten Zeilen werden akzeptiert oder zurückgewiesen.
None In den untergeordneten Zeilen wird keine Aktion ausgeführt. Dies ist die Standardeinstellung.

Beispiel

Im folgenden Beispiel wird ein ForeignKeyConstraint-Objekt erstellt, und es werden einige seiner Eigenschaften festgelegt (einschließlich der AcceptRejectRule-Regel) und dem ConstraintCollection-Objekt eines DataTable-Objekts hinzugefügt.

static void CreateConstraint(DataSet dataSet,
    string table1, string table2, string column1, string column2)
{
    // Declare parent column and child column variables.
    DataColumn parentColumn, childColumn;
    ForeignKeyConstraint foreignKeyConstraint;

    // Set parent and child column variables.
    parentColumn = dataSet.Tables[table1]?.Columns[column1] ??
        throw new NullReferenceException($"{nameof(CreateConstraint)}: {table1}.{column1} not found");
    childColumn = dataSet.Tables[table2]?.Columns[column2] ??
        throw new NullReferenceException($"{nameof(CreateConstraint)}: {table2}.{column2} not found");
    foreignKeyConstraint = new ForeignKeyConstraint
       ("SupplierForeignKeyConstraint", parentColumn, childColumn)
    {
        // Set null values when a value is deleted.
        DeleteRule = Rule.SetNull,
        UpdateRule = Rule.Cascade,
        AcceptRejectRule = AcceptRejectRule.None
    };

    // Add the constraint, and set EnforceConstraints to true.
    dataSet.Tables[table1]?.Constraints.Add(foreignKeyConstraint);
    dataSet.EnforceConstraints = true;
}
Private Sub CreateConstraint(dataSet As DataSet, _
   table1 As String, table2 As String, _
   column1 As String, column2 As String)

    ' Declare parent column and child column variables.
    Dim parentColumn As DataColumn
    Dim childColumn As DataColumn
    Dim foreignKeyConstraint As ForeignKeyConstraint

    ' Set parent and child column variables.
    parentColumn = dataSet.Tables(table1).Columns(column1)
    childColumn = dataSet.Tables(table2).Columns(column2)
    foreignKeyConstraint = New ForeignKeyConstraint _
       ("SupplierForeignKeyConstraint", parentColumn, childColumn)

    ' Set null values when a value is deleted.
    foreignKeyConstraint.DeleteRule = Rule.SetNull
    foreignKeyConstraint.UpdateRule = Rule.Cascade
    foreignKeyConstraint.AcceptRejectRule = AcceptRejectRule.None

    ' Add the constraint, and set EnforceConstraints to true.
    dataSet.Tables(table1).Constraints.Add(foreignKeyConstraint)
    dataSet.EnforceConstraints = True
End Sub

UniqueConstraint

Das UniqueConstraint-Objekt, das entweder einer einzelnen Spalte oder einem Array aus Spalten in DataTable zugewiesen werden kann, stellt sicher, dass alle Daten in den angegebenen Spalten pro Zeile eindeutig sind. Sie können eine eindeutige Einschränkung für eine Spalte oder ein Array aus Spalten erstellen, indem Sie den UniqueConstraint-Konstruktor verwenden. Übergeben Sie das resultierende UniqueConstraint-Objekt an die Add-Methode der Constraints-Eigenschaft der Tabelle. Bei dieser handelt es sich um ein ConstraintCollection-Element. Sie können auch Konstruktorargumente an mehrere Überladungen der Add-Methode eines ConstraintCollection-Elements übergeben, um UniqueConstraint zu erstellen. Beim Erstellen von UniqueConstraint für eine oder mehrere Spalten können Sie optional festlegen, ob die Spalten einen Primärschlüssel darstellen.

Sie können auch eine eindeutige Einschränkung für eine Spalte erstellen, indem Sie die Unique-Eigenschaft der Spalte auf true festlegen. Alternativ werden alle möglicherweise vorhandenen eindeutigen Einschränkungen entfernt, wenn die Unique-Eigenschaft einer einzelnen Spalte auf false festgelegt wird. Durch das Definieren einer oder mehrerer Spalten als Primärschlüssel für eine Tabelle wird automatisch eine eindeutige Einschränkung für die angegebene(n) Spalte(n) erstellt. Wenn Sie eine Spalte aus der PrimaryKey-Eigenschaft von DataTable entfernen, wird UniqueConstraint entfernt.

Im folgenden Beispiel wird UniqueConstraint für zwei Spalten von DataTable erstellt.

Dim custTable As DataTable = custDS.Tables("Customers")  
Dim custUnique As UniqueConstraint = _  
    New UniqueConstraint(New DataColumn()   {custTable.Columns("CustomerID"), _  
    custTable.Columns("CompanyName")})  
custDS.Tables("Customers").Constraints.Add(custUnique)  
DataTable custTable = custDS.Tables["Customers"];  
UniqueConstraint custUnique = new UniqueConstraint(new DataColumn[]
    {custTable.Columns["CustomerID"],
    custTable.Columns["CompanyName"]});  
custDS.Tables["Customers"].Constraints.Add(custUnique);  

Siehe auch