您可以使用條件約束來強制執行 中 DataTable數據的限制,以維護數據的完整性。 條件約束是套用至數據行或相關數據行的自動規則,會在數據列的值以某種方式改變時決定動作過程。 當 的 System.Data.DataSet.EnforceConstraints
屬性為 DataSet 時,會強制執行條件約束。 若需查看如何設定EnforceConstraints
屬性的程式碼範例,請參閱EnforceConstraints參考主題。
ADO.NET 有兩種條件約束: ForeignKeyConstraint 和 UniqueConstraint。 根據預設,當您藉由將 新增 DataRelation 至 DataSet,建立兩個或多個數據表之間的關聯性時,會自動建立這兩個條件約束。 不過,您可以在建立關聯時指定 createConstraints = false 來停用此行為。
外鍵約束
ForeignKeyConstraint 會強制執行有關如何傳播相關數據表更新和刪除的規則。 例如,如果更新或刪除一個數據表之數據列中的值,而且在一或多個相關數據表中也會使用相同的值, ForeignKeyConstraint 會決定相關數據表中會發生什麼事。
DeleteRule UpdateRule 的 和 屬性會定義當使用者嘗試刪除或更新相關數據表中的數據列時要採取的動作。 下表描述 ForeignKeyConstraint 的 DeleteRule 和 UpdateRule 屬性所提供的不同設定。
規則設定 | 說明 |
---|---|
級聯 | 刪除或更新相關的數據列。 |
SetNull | 將相關數據列中的值設定為 DBNull。 |
設為預設 | 將相關數據列中的值設定為預設值。 |
沒有 | 對相關數據列不採取任何動作。 這是預設值。 |
ForeignKeyConstraint 可以限制相關欄位的變更,以及傳播變更。 根據數據行 ForeignKeyConstraint 所設定的屬性而定,如果 DataSet 的 EnforceConstraints 屬性為 true,則對父數據列執行特定作業會導致例外狀況。 例如,如果 ForeignKeyConstraint 的 DeleteRule 屬性為 None,則如果父數據列有任何子數據列,則無法刪除該數據列。
您可以使用 ForeignKeyConstraint 建構函式,在單一數據行或數據行陣列之間建立外鍵條件約束。 將產生的ForeignKeyConstraint對象傳遞至數據表的 Constraints 屬性的 Add 方法,也就是 ConstraintCollection。 您也可以將建構函式自變數傳遞至 ConstraintCollection 之 Add 方法的數個多載,以建立 ForeignKeyConstraint。
建立 ForeignKeyConstraint 時,您可以將 DeleteRule 和 UpdateRule 值傳遞至建構函式做為自變數,也可以將它們設定為屬性,如下列範例所示( 其中 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);
接受拒絕規則
您可以使用 AcceptChanges 方法接受數據列的變更,或使用 DataSet、DataTable 或 DataRow 的 RejectChanges 方法取消。 當 DataSet 包含 ForeignKeyConstraints 時,叫用 AcceptChanges 或 RejectChanges 方法會強制執行 AcceptRejectRule。 ForeignKeyConstraint 的 AcceptRejectRule 屬性會決定在父數據列上呼叫 AcceptChanges 或 RejectChanges 時,將在子數據列上採取哪些動作。
下表列出 AcceptRejectRule 的可用設定。
規則設定 | 說明 |
---|---|
級聯 | 接受或拒絕子數據列的變更。 |
沒有 | 對子數據列不採取任何動作。 這是預設值。 |
範例
下列範例會建立ForeignKeyConstraint,並設定多個屬性,包括AcceptRejectRule,然後將它新增至ConstraintCollection物件的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 物件可以指派給單一數據行或 DataTable 中的數據行陣列,可確保指定資料行或數據行中的所有數據都是每個數據列的唯一數據。 您可以使用 UniqueConstraint 建構函式,為數據行或數據行陣列建立唯一條件約束。 將產生的 UniqueConstraint 對象傳遞至數據表之 Constraints 屬性的 Add 方法,這是 ConstraintCollection。 您也可以將建構函式自變數傳遞至 ConstraintCollection 之 Add 方法的數個多載,以建立 UniqueConstraint。 為數據行或資料行建立 UniqueConstraint 時,您可以選擇性地指定資料行或數據行是否為主鍵。
您也可以將數據行的 Unique 屬性設定為 true,為數據行建立唯一條件約束。 或者,將單一數據行的 Unique 屬性設定為 false 會移除可能存在的任何唯一條件約束。 將數據行或數據行定義為數據表的主鍵,會自動為指定的數據行或數據行建立唯一條件約束。 如果您移除 DataTable 的 PrimaryKey 屬性中的資料行,則會移除 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);