数据表约束

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

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

ForeignKeyConstraint

执行 ForeignKeyConstraint 以强制规定如何传播相关表的更新和删除。 例如,如果更新或删除了一张表中一行的值,并且该相同的值也用于一个或多个相关表中,则 ForeignKeyConstraint 决定了在相关表中会发生什么。

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

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

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

可以使用构造函数在单个列之间或列 ForeignKeyConstraint 数组之间创建外键约束。 将生成的 ForeignKeyConstraint 对象传递给 AddConstraints 属性的方法,即 ConstraintCollection。 还可以将构造函数参数传递给 方法的多个重载,以创建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 方法接受对 DataSetDataTableDataRow 的行的更改,或者使用 RejectChanges 方法取消这些更改。 DataSet当包含 ForeignKeyConstraints 时,调用 AcceptChanges or RejectChanges 方法将强制实施 AcceptRejectRuleAcceptRejectRule属性决定在父行上调用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 对象传递给 AddConstraints 属性的方法,即 ConstraintCollection。 您还可以将构造函数参数传递到 ConstraintCollectionAdd 方法的多个重载,以创建 UniqueConstraint。 在为一个或多个列创建UniqueConstraint时,你可以选择指定这些列是否为主键。

还可以通过将列的属性设置为 Uniquetrue 来为列创建唯一约束。 或者,将单个列的属性设置为Uniquefalse删除可能存在的任何唯一约束。 将列或列定义为表的主键将自动为指定的列或列创建唯一约束。 如果从 PrimaryKey 属性中删除 DataTable 的一列,则会删除 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);

另请参阅