制約を使用すると、データの整合性を維持するために、 DataTable内のデータに制限を適用できます。 制約は、列または関連する列に適用される自動ルールであり、行の値が何らかの形で変更されたときにアクションの経過を決定します。 制約は、System.Data.DataSet.EnforceConstraints
の DataSet プロパティが true の場合に適用されます。 EnforceConstraints
プロパティを設定する方法を示すコード例については、EnforceConstraintsリファレンス トピックを参照してください。
ADO.NET には、 ForeignKeyConstraint と UniqueConstraintの 2 種類の制約があります。 既定では、DataRelation にを追加して複数のテーブル間にリレーションシップを作成すると、両方の制約が自動的に作成されます。 ただし、リレーションシップの作成時に createConstraints = false を指定することで、この動作を無効にできます。
外部キー制約
ForeignKeyConstraint は、関連テーブルの更新と削除の伝達方法に関する規則を適用します。 たとえば、1 つのテーブルの行の値が更新または削除され、同じ値が 1 つ以上の関連テーブルでも使用されている場合、 ForeignKeyConstraint によって関連テーブルでの動作が決定されます。
DeleteRule のUpdateRuleプロパティとプロパティは、ユーザーが関連テーブルの行を削除または更新しようとしたときに実行されるアクションを定義します。 次の表では、ForeignKeyConstraint の DeleteRule プロパティと UpdateRule プロパティで使用できるさまざまな設定について説明します。
ルールの設定 | 説明 |
---|---|
カスケード | 関連する行を削除または更新します。 |
SetNull | 関連する行の値を DBNull に設定します。 |
デフォルトに設定 | 関連する行の値を既定値に設定します。 |
なし | 関連する行に対してアクションを実行しません。 これが既定値です。 |
ForeignKeyConstraint では、関連する列に対する変更を制限したり、反映したりできます。 列の ForeignKeyConstraint に設定されたプロパティに応じて、DataSet の EnforceConstraints プロパティが true の場合、親行に対して特定の操作を実行すると例外が発生します。 たとえば、ForeignKeyConstraint の DeleteRule プロパティが None の場合、親行に子行がある場合は削除できません。
ForeignKeyConstraint コンストラクターを使用して、単一列間または列配列間に外部キー制約を作成できます。 結果の ForeignKeyConstraint オブジェクトを、テーブルの Constraints プロパティ (ConstraintCollection) の Add メソッドに渡します。 また、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
ユニーク制約
単一の列または DataTable 内の列の配列に割り当てることができる UniqueConstraint オブジェクトは、指定された列または列のすべてのデータが行ごとに一意であることを保証します。 UniqueConstraint コンストラクターを使用して、列または列の配列の一意制約を作成できます。 結果の UniqueConstraint オブジェクトを、テーブルの Constraints プロパティ (ConstraintCollection) の Add メソッドに渡します。 また、ConstraintCollection のAdd メソッドのいくつかのオーバーロードにコンストラクター引数を渡して UniqueConstraint を作成することもできます。 列または列に UniqueConstraint を作成するときに、必要に応じて列または列を主キーにするかどうかを指定できます。
列のユニーク制約を作成するには、列の Unique プロパティをtrue に設定することもできます。 または、1 つの列の Unique プロパティを false に設定すると、存在する可能性のある一意の制約が削除されます。 テーブルの主キーとして列または列を定義すると、指定した列に対して一意の制約が自動的に作成されます。 DataTable の PrimaryKey プロパティから列を削除すると、UniqueConstraint が削除されます。
次の例では、DataTable の 2 つの列に 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);