Ограничения таблиц данных
Ограничения позволяют принудительно поддерживать целостность данных DataTable. Ограничение представляет собой автоматическое правило, применяемое к столбцу или связанным столбцам и определяющее порядок действий при каком-либо изменении содержимого строки. Ограничения применяются, когда System.Data.DataSet.EnforceConstraints
свойство DataSet true. Пример кода, показывающий, как установить свойство EnforceConstraints
, см. в разделе справки EnforceConstraints.
В ADO.NET имеется два типа ограничений: ForeignKeyConstraint и UniqueConstraint. По умолчанию оба ограничения создаются автоматически при создании связи между двумя или более таблицами путем добавления DataRelation в набор данных. Однако это поведение можно отключить, указав значение false createConstraints = при создании отношения.
Ограничение ForeignKeyConstraint
ForeignKeyConstraint применяет правила о распространении обновлений и удалений связанных таблиц. Например, если значение в строке одной таблицы обновляется или удаляется, а это же значение также используется в одной или нескольких связанных таблицах, foreignKeyConstraint определяет, что происходит в связанных таблицах.
UpdateRule Свойства DeleteRule ForeignKeyConstraint определяют действие, выполняемое при попытке пользователя удалить или обновить строку в связанной таблице. В следующей таблице описаны различные параметры, доступные для свойств DeleteRule и UpdateRule для ForeignKeyConstraint.
Установка правил | Description |
---|---|
Cascade | Удалить или обновить связанные строки. |
SetNull | Задайте значения в связанных строках для DBNull. |
SetDefault | Присвоить столбцам в связанных строках значение по умолчанию. |
Не допускается | Не выполнять никаких действий в связанных строках. Это значение по умолчанию. |
ForeignKeyConstraint может ограничить, а также распространять изменения связанных столбцов. В зависимости от набора свойств для столбца ForeignKeyConstraint, если свойство EnforceConstraints набора данных имеет значение true, выполнение определенных операций в родительской строке приведет к исключению. Например, если свойство DeleteRule для ForeignKeyConstraint равно None, родительская строка не может быть удалена, если она имеет дочерние строки.
Можно создать ограничение внешнего ключа между отдельными столбцами или между массивом столбцов с помощью конструктора ForeignKeyConstraint . Передайте результирующий объект ForeignKeyConstraint методу Add свойства "Ограничения таблицы", являющегося объектом ConstraintCollection. Аргументы конструктора также можно передать нескольким перегрузкам метода Add объекта ConstraintCollection для создания 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 или отменить с помощью метода RejectChanges набора данных, DataTable или DataRow. Если набор данных содержит ForeignKeyConstraints, вызывает метод AcceptChanges или RejectChanges, применяет метод AcceptRejectRule. Свойство AcceptRejectRule foreignKeyConstraint определяет, какое действие будет выполняться в дочерних строках при вызове AcceptChanges или RejectChanges в родительской строке.
В следующей таблице перечислены доступные параметры для AcceptRejectRule.
Установка правил | Description |
---|---|
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 . Передайте результирующий объект UniqueConstraint методу Add свойства "Ограничения таблицы", являющегося объектом ConstraintCollection. Аргументы конструктора также можно передать нескольким перегрузкам метода Add объекта ConstraintCollection, чтобы создать UniqueConstraint. При создании UniqueConstraint для столбца или столбцов можно указать, является ли столбец или столбцы первичным ключом.
Вы также можете создать уникальное ограничение для столбца, задав для столбца значение true уникального свойства. Кроме того, при задании свойства Unique одного столбца значение false удаляет любое уникальное ограничение, которое может существовать. При определении столбца или группы столбцов в качестве первичного ключа таблицы автоматически создается ограничение уникальности для заданного столбца или группы столбцов. При удалении столбца из свойства PrimaryKey dataTable удаляется UniqueConstraint.
В следующем примере создается UniqueConstraint для двух столбцов DataTable.
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);