Vincoli DataTable

I vincoli consentono di applicare restrizioni ai dati di una DataTable, in modo da garantire l'integrità di tali dati. Un vincolo è una regola automatica applicata a una colonna, o a colonne correlate, che consente di determinare le operazioni da eseguire in caso di modifica del valore di una riga. I vincoli vengono applicati quando la proprietà dell'oggetto System.Data.DataSet.EnforceConstraintsDataSet è true. Per un esempio di codice che illustra come impostare la proprietà EnforceConstraints, vedere l'argomento relativo a EnforceConstraints.

In ADO.NET sono disponibili due tipi di vincoli: ForeignKeyConstraint e UniqueConstraint. Per impostazione predefinita, entrambi i vincoli vengono creati automaticamente quando si crea una relazione tra due o più tabelle aggiungendo un oggetto DataRelation a DataSet. Tuttavia, è possibile disabilitare questo comportamento specificando createConstraints = false durante la creazione della relazione.

ForeignKeyConstraint

Un foreignKeyConstraint applica regole sulla modalità di propagazione degli aggiornamenti ed eliminazioni alle tabelle correlate. Ad esempio, se un valore in una riga di una tabella viene aggiornato o eliminato e lo stesso valore viene usato anche in una o più tabelle correlate, un foreignKeyConstraint determina cosa accade nelle tabelle correlate.

Le DeleteRule proprietà e UpdateRule di ForeignKeyConstraint definiscono l'azione da eseguire quando l'utente tenta di eliminare o aggiornare una riga in una tabella correlata. Nella tabella seguente vengono descritte le diverse impostazioni disponibili per le proprietà DeleteRule e UpdateRule di ForeignKeyConstraint.

Impostazione della regola Descrizione
Cascata Elimina o aggiorna righe correlate.
SetNull Impostare i valori nelle righe correlate a DBNull.
SetDefault Imposta i valori delle righe correlate sul valore predefinito.
Nessuno Non viene eseguita alcuna operazione sulle righe correlate. Questo è il valore predefinito.

Un foreignKeyConstraint può limitare, oltre a propagare le modifiche alle colonne correlate. A seconda delle proprietà impostate per ForeignKeyConstraint di una colonna, se la proprietà EnforceConstraintsdell'oggetto DataSet è true, l'esecuzione di determinate operazioni nella riga padre comporterà un'eccezione. Ad esempio, se la proprietà DeleteRule dell'oggetto ForeignKeyConstraint è None, non è possibile eliminare una riga padre se contiene righe figlio.

È possibile creare un vincolo di chiave esterna tra singole colonne o tra una matrice di colonne usando il costruttore ForeignKeyConstraint . Passare l'oggetto ForeignKeyConstraint risultante al metodo Add della proprietà Constraints della tabella, ovvero un Oggetto ConstraintCollection. È anche possibile passare gli argomenti del costruttore a diversi overload del metodo Add di un Oggetto ConstraintCollection per creare un oggetto ForeignKeyConstraint.

Quando si crea un valore ForeignKeyConstraint, è possibile passare i valori DeleteRule e UpdateRule al costruttore come argomenti oppure è possibile impostarli come proprietà come nell'esempio seguente (dove il valore DeleteRule è impostato su Nessuno).

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

Le modifiche alle righe possono essere accettate usando il metodo AcceptChanges o annullate usando il metodo RejectChanges di DataSet, DataTable o DataRow. Quando un oggetto DataSet contiene ForeignKeyConstraints, richiamando i metodi AcceptChanges o RejectChanges applica acceptRejectRule. La proprietà AcceptRejectRule di ForeignKeyConstraint determina quale azione verrà eseguita nelle righe figlio quando AcceptChanges o RejectChanges viene chiamata nella riga padre.

Nella tabella seguente sono elencate le impostazioni disponibili per AcceptRejectRule.

Impostazione della regola Descrizione
Cascata Consente di accettare o rifiutare le modifiche alle righe figlio.
Nessuno Non viene eseguita alcuna operazione sulle righe figlio. Questo è il valore predefinito.

Esempio

Nell'esempio seguente viene creato un oggetto ForeignKeyConstraint, ne vengono impostate alcune proprietà, tra cui AcceptRejectRule, nonché viene aggiunto all'oggetto ConstraintCollection di un oggetto 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'oggetto UniqueConstraint , che può essere assegnato a una singola colonna o a una matrice di colonne in una Tabella dati, garantisce che tutti i dati nella colonna o nelle colonne specificate siano univoci per riga. È possibile creare un vincolo univoco per una colonna o una matrice di colonne usando il costruttore UniqueConstraint . Passare l'oggetto UniqueConstraint risultante al metodo Add della proprietà Constraints della tabella, ovvero un Oggetto ConstraintCollection. È anche possibile passare gli argomenti del costruttore a diversi overload del metodo Add di un Oggetto ConstraintCollection per creare un oggetto UniqueConstraint. Quando si crea un oggetto UniqueConstraint per una colonna o una colonna, è possibile specificare facoltativamente se la colonna o le colonne sono una chiave primaria.

È anche possibile creare un vincolo univoco per una colonna impostando la proprietà Unique della colonna su true. In alternativa, impostare la proprietà Unique di una singola colonna su false rimuove qualsiasi vincolo univoco che può esistere. La definizione di una o più colonne come chiave primaria per una tabella consentirà di creare automaticamente un vincolo univoco per la colonna o le colonne specificate. Se si rimuove una colonna dalla proprietà PrimaryKey di una tabella Dati, uniqueConstraint viene rimossa.

Nell'esempio seguente viene creato un oggetto UniqueConstraint per due colonne di una Tabella dati.

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

Vedi anche