数据表约束

可以使用约束对DataTable中的数据强制实施限制,以保持数据的完整性。 约束是应用于列或相关列的自动规则,用于确定行值发生某种更改时的作过程。 当System.Data.DataSet.EnforceConstraints属性DataSettrue时,约束被强制实施。 有关显示如何设置 EnforceConstraints 属性的代码示例,请参见 EnforceConstraints 参考主题。

ADO.NET 中有两种类型的约束: ForeignKeyConstraintUniqueConstraint. 默认情况下,当在DataRelation中通过添加来创建两个或多个表之间的关系时,两个约束都会自动创建。 但是,可以通过在创建关系时指定 createConstraints = false 来禁用此行为。

ForeignKeyConstraint

ForeignKeyConstraint 强制实施有关如何传播相关表的更新和删除的规则。 例如,如果更新或删除了一行中的值,并且同一值也用于一个或多个相关表中, ForeignKeyConstraint 将确定相关表中发生的情况。

DeleteRuleUpdateRule 属性定义了用户尝试删除或更新相关表中的行时要执行的操作。 下表描述了 ForeignKeyConstraintDeleteRuleUpdateRule 属性可用的不同设置。

规则设置 DESCRIPTION
级联 删除或更新相关行。
SetNull 将相关行中的值设置为 DBNull
设置默认 将相关行中的值设置为默认值。
没有 对相关行不执行任何操作。 这是默认值。

ForeignKeyConstraint 可以限制对相关列的更改以及传播更改。 根据为列的ForeignKeyConstraint设置的属性,如果DataSetEnforceConstraints属性为 true,对父行执行某些操作将导致异常。 例如,如果 ForeignKeyConstraintDeleteRule 属性为 None,则如果父行具有任何子行,则无法删除父行。

可以使用 ForeignKeyConstraint 构造函数在单个列之间或列数组之间创建外键约束。 将生成的 ForeignKeyConstraint 对象传递给表的 Constraints 属性的 Add 方法,该属性是 ConstraintCollection。 还可以将构造函数参数传递给 ConstraintCollection 的多个 Add 方法的重载,以创建 ForeignKeyConstraint

创建 ForeignKeyConstraint 时,可以将 DeleteRuleUpdateRule 值作为参数传递给构造函数,也可以将其设置为属性(其中 DeleteRule 值设置为 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

可以使用 AcceptChanges 方法接受对行的更改,也可以使用 DataSetDataTableDataRowRejectChanges 方法取消更改。 当数据集包含 ForeignKeyConstraints 时,调用 AcceptChangesRejectChanges 方法将强制实施 AcceptRejectRuleForeignKeyConstraint 中的 AcceptRejectRule 属性会在对父行调用 AcceptChangesRejectChanges 时,确定对子行执行哪些操作。

下表列出了 AcceptRejectRule 的可用设置。

规则设置 DESCRIPTION
级联 接受或拒绝对子行的更改。
没有 对子行不执行任何操作。 这是默认值。

示例:

以下示例创建一个 ForeignKeyConstraint,设置其多个属性,包括 AcceptRejectRule,并将其添加到 ConstraintCollectionDataTable 对象中。

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

UniqueConstraint 对象可以分配给单个列或 DataTable 中的列数组,可确保指定列或列中的所有数据都是每行唯一的。 可以使用 UniqueConstraint 构造函数为列或列数组创建唯一约束。 将生成的 UniqueConstraint 对象传递给表的 Constraints 属性的 Add 方法,该属性是 ConstraintCollection。 还可以将构造函数参数传递给 ConstraintCollectionAdd 方法的多个重载,以创建 UniqueConstraint。 为列或列创建 UniqueConstraint 时,可以选择指定列或列是否为主键。

还可以通过将列的 Unique 属性设置为 true 来为列创建唯一约束。 或者将单个列的唯一属性设置为false,会删除可能存在的任何唯一约束。 将列或列定义为表的主键将自动为指定的列或列创建唯一约束。 如果从 DataTablePrimaryKey 属性中删除列,则会删除 UniqueConstraint

以下示例为 DataTable 的两列创建 UniqueConstraint

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

另请参阅