DataTable 제약 조건
제약 조건을 사용하여 DataTable의 데이터를 제한함으로써 데이터 무결성을 유지할 수 있습니다. 제약 조건은 자동 규칙이기 때문에 행 값이 조금이라도 변경되면 열 또는 관련 열에 적용되어 작업 과정을 결정합니다. 제약 조건은 DataSet의 System.Data.DataSet.EnforceConstraints
속성이 true인 경우에 적용됩니다. EnforceConstraints
속성을 설정하는 방법을 보여 주는 코드 예제는 EnforceConstraints 참조 항목을 참조하세요.
ADO.NET에는 ForeignKeyConstraint 및 UniqueConstraint의 두 가지 제약 조건이 있습니다. 기본적으로 DataRelation을 DataSet에 추가하여 둘 이상의 테이블 간에 관계를 만들면 두 제약 조건이 자동으로 만들어집니다. 그러나 관계를 만들 때 createConstraints = false를 지정하여 이 동작을 사용하지 않도록 설정할 수 있습니다.
ForeignKeyConstraint
ForeignKeyConstraint는 관련 테이블에 대한 업데이트 및 삭제를 전파하는 방법에 대한 규칙을 적용합니다. 예를 들어, 특정 테이블의 행 값이 업데이트되거나 삭제되는 경우 또는 이 값이 하나 이상의 관련 테이블에서 사용되는 경우, ForeignKeyConstraint는 관련 테이블에서 실행되는 동작을 결정합니다.
ForeignKeyConstraint의 DeleteRule 및 UpdateRule 속성은 사용자가 관련 테이블의 행을 삭제하거나 업데이트할 때 수행해야 하는 작업을 정의합니다. 다음 표에서는 ForeignKeyConstraint의 DeleteRule 및 UpdateRule 속성에서 사용할 수 있는 다양한 설정에 대해 설명합니다.
규칙 설정 | 설명 |
---|---|
Cascade | 관련 행을 삭제하거나 업데이트합니다. |
SetNull | 관련 행의 값을 DBNull로 설정합니다. |
SetDefault | 관련 행의 값을 기본값으로 설정합니다. |
없음 | 관련 행에 대해 아무 동작도 수행하지 않습니다. 기본값입니다. |
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);
AcceptRejectRule
행에 대한 변경 내용은 AcceptChanges 메서드를 사용하여 적용하거나 DataSet, DataTable 또는 DataRow의 RejectChanges 메서드를 사용하여 취소할 수 있습니다. DataSet에 ForeignKeyConstraints가 포함되어 있는 경우 AcceptChanges 또는 RejectChanges 메서드는 AcceptRejectRule을 적용합니다. 부모 행에서 AcceptChanges 또는 RejectChanges가 호출되는 경우, ForeignKeyConstraint의 AcceptRejectRule 속성은 자식 행에서 수행되는 동작을 결정합니다.
다음 표에서는 AcceptRejectRule에 대해 사용 가능한 설정의 목록을 보여 줍니다.
규칙 설정 | 설명 |
---|---|
Cascade | 자식 행의 변경을 승인하거나 거부합니다. |
없음 | 자식 행에 대해 아무 동작도 수행하지 않습니다. 기본값입니다. |
예시
다음 예제에서는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
UniqueConstraint 개체는 DataTable의 단일 열 또는 열 배열에 할당될 수 있습니다. 이 개체를 사용하면 지정한 하나 이상의 열에서 모든 데이터가 행별로 고유한지 확인할 수 있습니다. 또한 UniqueConstraint 생성자를 사용하면 열 또는 열 배열의 UNIQUE 제약 조건을 만들 수 있습니다. 생성된 UniqueConstraint 개체를 테이블의 Constraints 속성에 있는 Add 메서드로 전달합니다. 이 속성은 ConstraintCollection입니다. ConstraintCollection의 Add 메서드의 여러 오버로드에 생성자 인수를 전달하여 UniqueConstraint를 만들 수도 있습니다. 하나 이상의 열에 대해 UniqueConstraint를 만들 때 해당 열이 기본 키인지 여부를 선택적으로 지정할 수 있습니다.
열의 Unique 속성을 true로 설정하여 열에 대해 UNIQUE 제약 조건을 만들 수도 있습니다. 또는 단일 열의 Unique 속성을 false로 설정하면 UNIQUE 제약 조건(있는 경우)이 제거됩니다. 하나 이상의 열을 테이블의 기본 키로 정의하면 지정한 열에 대한 UNIQUE 제약 조건이 자동으로 만들어집니다. 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);