Contraintes de DataTable

Vous pouvez utiliser des contraintes pour appliquer des restrictions sur les données dans un objet DataTable afin de conserver l'intégrité des données. Une contrainte est une règle automatique, appliquée à une ou plusieurs colonnes en relation, qui détermine l'action à réaliser lorsque la valeur d'une ligne est modifiée. Les contraintes sont appliquées quand la propriété System.Data.DataSet.EnforceConstraints de l’objet DataSet a la valeur true. Pour obtenir un exemple de code montrant comment définir la propriété EnforceConstraints, consultez la rubrique de référence EnforceConstraints.

Il y a deux types de contraintes dans ADO.NET : la ForeignKeyConstraint et la UniqueConstraint. Par défaut, ces deux contraintes sont automatiquement créées quand vous créez une relation entre plusieurs tables en ajoutant un objet DataRelation au DataSet. Toutefois, vous pouvez désactiver ce comportement en spécifiant createConstraints = false lors de la création de la relation.

ForeignKeyConstraint

Une ForeignKeyConstraint applique des règles sur la manière dont les mises à jour et les suppressions dans les tables connexes sont propagées. Par exemple, si une valeur d’une ligne d’une table est mise à jour ou supprimée et si cette valeur est également utilisée dans une ou plusieurs autres tables connexes, une ForeignKeyConstraint détermine l’action à réaliser dans les tables connexes.

Les propriétés DeleteRule et UpdateRule de la ForeignKeyConstraint définissent l’action à entreprendre quand l’utilisateur tente de supprimer ou de mettre à jour une ligne dans une table connexe. Le tableau suivant décrit les différents paramètres disponibles pour les propriétés DeleteRule et UpdateRule de la ForeignKeyConstraint.

Paramètre de règle Description
Cascade Supprime ou met à jour les lignes connexes.
SetNull Définit les valeurs dans les lignes connexes sur DBNull.
SetDefault Définit les valeurs des lignes connexes sur la valeur par défaut.
Aucun N'effectue aucune action sur les lignes connexes. Il s’agit de la valeur par défaut.

Une ForeignKeyConstraint peut limiter et propager les modifications dans les colonnes connexes. En fonction des propriétés définies pour la ForeignKeyConstraint d’une colonne et si la valeur true est attribuée ou non à la propriété EnforceConstraints du DataSet, certaines opérations réalisées dans la ligne parente peuvent provoquer une exception. Par exemple, si la propriété DeleteRule de la ForeignKeyConstraint a la valeur None, il est impossible de supprimer une ligne parente possédant des lignes enfants.

Vous pouvez créer une contrainte de clé étrangère entre des colonnes uniques ou entre un tableau de colonnes en utilisant le constructeur ForeignKeyConstraint. Passez l’objet ForeignKeyConstraint résultant à la méthode Add de la propriété Constraints de la table, qui est un ConstraintCollection. Vous pouvez également passer des arguments de constructeur à plusieurs surcharges de la méthode Add d’un ConstraintCollection pour créer une ForeignKeyConstraint.

Lors de la création d’une ForeignKeyConstraint, vous pouvez passer les valeurs de DeleteRule et UpdateRule comme arguments au constructeur ou les définir comme propriétés, comme dans l’exemple suivant (où DeleteRule a la valeur None).

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

Les modifications de lignes peuvent être acceptées à l’aide de la méthode AcceptChanges ou annulées à l’aide de la méthode RejectChanges du DataSet, DataTable ou DataRow. Quand un DataSet contient des ForeignKeyConstraints, l’appel aux méthodes AcceptChanges ou RejectChanges applique l’AcceptRejectRule. La propriété AcceptRejectRule de la ForeignKeyConstraint détermine l’action à réaliser dans les lignes enfants lors de l’appel à AcceptChanges ou RejectChanges dans la ligne parente.

Le tableau suivant liste les paramètres possibles pour AcceptRejectRule.

Paramètre de règle Description
Cascade Accepte ou rejette les modifications des lignes enfants.
Aucun N'effectue aucune action sur les lignes enfants. Il s’agit de la valeur par défaut.

Exemple

L'exemple suivant crée un objet ForeignKeyConstraint, définit plusieurs de ses propriétés, notamment la AcceptRejectRule, et l'ajoute à la ConstraintCollection d'un objet DataTable.

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

L’objet UniqueConstraint, qui peut être assigné soit à une seule colonne, soit à un tableau de colonnes d’un DataTable, garantit que toutes les données des colonnes spécifiées sont uniques dans une ligne. Vous pouvez créer une contrainte unique pour une colonne ou un tableau de colonnes en utilisant le constructeur UniqueConstraint. Passez l’objet UniqueConstraint résultant à la méthode Add de la propriété Constraints de la table, qui est un ConstraintCollection. Vous pouvez également passer des arguments de constructeur à plusieurs surcharges de la méthode Add d’un ConstraintCollection pour créer un UniqueConstraint. Lors de la création d’un UniqueConstraint pour une ou plusieurs colonnes, vous pouvez spécifier si les colonnes correspondent à des clés primaires.

Vous pouvez également créer une contrainte unique pour une colonne en attribuant la valeur true à la propriété Unique de la colonne. L’affectation de la valeur false à la propriété Unique d’une colonne unique supprime toute contrainte existante. Lorsque vous définissez une ou plusieurs colonnes comme clé primaire d'une table, une contrainte unique est automatiquement créée pour les colonnes spécifiées. Si vous supprimez une colonne de la propriété PrimaryKey d’un DataTable, UniqueConstraint est supprimé.

L’exemple suivant créé un UniqueConstraint pour deux colonnes d’un DataTable.

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);  

Voir aussi