제약 조건을 사용하여 데이터의 무결성을 유지하기 위해 데이터에 DataTable대한 제한을 적용할 수 있습니다. 제약 조건은 열 또는 관련 열에 적용되는 자동 규칙으로, 행 값이 어떻게든 변경될 때의 작업 과정을 결정합니다.
System.Data.DataSet.EnforceConstraints
의 해당 속성이 DataSet일 때 제약 조건이 적용됩니다. 코드 예제에서 EnforceConstraints
속성을 설정하는 방법을 보여줄 수 있는 EnforceConstraints 참조 항목을 확인하세요.
ADO.NET ForeignKeyConstraint 제약 조건과 UniqueConstraint두 가지 제약 조건이 있습니다. 기본적으로 두 제약 조건은 DataRelation에 추가 하여 둘 이상의 테이블 간에 관계를 만들 때 자동으로 만들어집니다. 그러나 관계를 만들 때 createConstraints = false 를 지정하여 이 동작을 사용하지 않도록 설정할 수 있습니다.
외래 키 제약 조건
ForeignKeyConstraint는 관련 테이블에 대한 업데이트 및 삭제가 전파되는 방법에 대한 규칙을 적용합니다. 예를 들어 한 테이블의 행에 있는 값이 업데이트되거나 삭제되고 하나 이상의 관련 테이블에서도 동일한 값이 사용되는 경우 ForeignKeyConstraint 는 관련 테이블에서 발생하는 동작을 결정합니다.
DeleteRule의 속성 및 UpdateRule 속성은 사용자가 관련 테이블의 행을 삭제하거나 업데이트하려고 할 때 수행할 작업을 정의합니다. 다음 표에서는 ForeignKeyConstraint의 DeleteRule 및 UpdateRule 속성에 사용할 수 있는 다양한 설정을 설명합니다.
규칙 설정 | 설명 |
---|---|
캐스케이드 | 관련 행을 삭제하거나 업데이트합니다. |
SetNull | 관련 행의 값을 DBNull로 설정합니다. |
기본값 설정 | 관련 행의 값을 기본값으로 설정합니다. |
없음 | 관련 행에 대해 아무 작업도 수행하지 않습니다. 기본값입니다. |
ForeignKeyConstraint는 관련 열에 대한 변경 내용을 제한하고 전파할 수 있습니다. 열의 ForeignKeyConstraint에 대해 설정된 속성에 따라 DataSet의 EnforceConstraints 속성이 true이면 부모 행에서 특정 작업을 수행하면 예외가 발생합니다. 예를 들어 ForeignKeyConstraint의 DeleteRule 속성이 None이면 자식 행이 있는 경우 부모 행을 삭제할 수 없습니다.
ForeignKeyConstraint 생성자를 사용하여 단일 열 또는 열 배열 간에 외래 키 제약 조건을 만들 수 있습니다. 결과 ForeignKeyConstraint 개체를 ConstraintCollection인 테이블의 Constraints 속성의 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 개체를 ConstraintCollection인 테이블의 Constraints 속성의 Add 메서드에 전달합니다. 또한 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);