Страница 7 из 8 УдалениеУдаляя иерархические данные, вы должны позаботиться о сохранении целостности базы данных. Каждая дочерняя строка должна ссылаться на допустимую строку в родительской таблице. Поэтому удалять строку из родительской таблицы нельзя до тех пор, пока существует хотя бы одна связанная с ней строка в дочерней таблице. В ADO.NET объект DataSet поддерживает каскадное удаление, которое позволяет удалять дочерние строки одновременно с соответствующими родительскими строками. Чтобы определить действия, необходимые при каких-либо изменениях строк в таблицах, вы должны указать ограничения внешнего ключа для двух таблиц в DataSet. Настройте метод DeleteProperty свойства ForeignKeyConstraint на один из подходящих режимов работы (по умолчанию операции выполняются в каскадном режиме). Автоматически генерируемая команда Delete Dim sqlConn As SqlConnection Dim sqlDAOrder As SqlDataAdapter Dim sqlDADetail As SqlDataAdapter Dim hierDS As DataSet Dim sqlCmdBldrOrder As SqlCommandBuilder Dim sqlCmdBldrDetail As SqlCommandBuilder Try ' Создать новый SQLConnection sqlConn = New SqlConnection(Common.getConnectionString) ' Создать новый объект SqlDataAdapter для таблицы Order sqlDAOrder = New SqlDataAdapter() ' Создать новый объект SqlDataAdapter для таблицы OrderDetails sqlDADetail = New SqlDataAdapter() ' Создать новый объект DataSet hierDS = New DataSet() ' Создать объекты CommandBuilder, автоматически формирующие команды sqlCmdBldrOrder = New SqlCommandBuilder(sqlDAOrder) sqlCmdBldrDetail = New SqlCommandBuilder(sqlDADetail) With sqlDAOrder ' Добавить объект SelectCommand sqlDAOrder.SelectCommand = New SqlCommand() ' Указать команду Select With .SelectCommand .CommandType = CommandType.StoredProcedure .CommandText = "GetOrderHeaders" .Connection = sqlConn End With ' Заполнить DataSet возвращенными данными .Fill(hierDS, "Orders") End With With sqlDADetail ' Добавить объект SelectCommand sqlDADetail.SelectCommand = New SqlCommand() ' Указать команду Select для объекта sqlDADetail With .SelectCommand .CommandText = "Select * from OrderDetails" .Connection = sqlConn End With ' Заполнить DataSet возвращенными данными .Fill(hierDS, "Details") End With ' Установить связь между таблицами hierDS.Relations.Add("Order_Detail", _ hierDS.Tables("Orders").Columns("OrderId"), _ hierDS.Tables("Details").Columns("OrderId")) ' Найти последнюю строку в таблице Orders orderRow = hierDS.Tables("Orders").Rows. _ Item(hierDS.Tables("Orders").Rows.Count - 1) ' Удалить строку из таблицы Orders. В результате этого ' автоматически удаляются соответствующие дочерние строки ' из таблицы Details в DataSet. orderRow.Delete() … ' Синхронизировать изменения с источником данных sqlDADetail.Update(hierDS, "Details") sqlDAOrder.Update(hierDS, "Orders") Catch E As Exception ' Обработать исключение Finally ' Выполнить очистку End Try
Для поддержания целостности данных дочерние строки должны удаляться первыми. Удалить родительские строки до удаления соответствующих дочерних строк нельзя. Поэтому обновление DataAdapter-объекта sqlDADetail для таблицы Details выполняется до обновления DataAdapter-объекта sqlDAOrder. Использование свойства DeleteCommandЧтобы указать собственное выражение Delete, выполняемое при вызове метода Update применительно к DataAdapter, используйте свойство DeleteCommand. Его значением является параметризированный запрос или хранимая процедура. Параметры для DeleteCommand определяются так же, как и для объекта Command. Для каждого параметра нужно задать свойство SourceColumn. Оно сообщает DataAdapter, в каком столбце содержится значение параметра. Dim sqlConn As SqlConnection Dim sqlDAOrder As SqlDataAdapter Dim sqlDaDetail As SqlDataAdapter Dim hierDS As DataSet Try ' Создать новый SQLConnection sqlConn = New SqlConnection(Common.getConnectionString) ' Создать новый объект SqlDataAdapter для таблицы Order sqlDAOrder = New SqlDataAdapter() ' Создать новый объект SqlDataAdapter для таблицы OrderDetails sqlDaDetail = New SqlDataAdapter() ' Создать новый DataSet hierDS = New DataSet() With sqlDAOrder ' Добавить объект SelectCommand .SelectCommand = New SqlCommand() ' Указать команду Select With .SelectCommand .CommandType = CommandType.StoredProcedure .CommandText = "GetOrderHeaders" .Connection = sqlConn End With ' Добавить объект DeleteCommand .DeleteCommand = New SqlCommand() ' Задать свойства DeleteCommand With .DeleteCommand .CommandType = CommandType.StoredProcedure .CommandText = "DeleteOrder" .Connection = sqlConn ' Определить параметры хранимой процедуры .Parameters.Add(New SqlParameter("@OrderId", SqlDbType.Int)) ' Настроить свойство SourceColumn .Parameters("@OrderId").SourceColumn = "OrderId" End With ' Заполнить DataSet возвращенными данными .Fill(hierDS, "Orders") End With With sqlDaDetail ' Добавить объект SelectCommand .SelectCommand = New SqlCommand() ' Указать команду Select With .SelectCommand .CommandType = CommandType.Text .CommandText = "Select * from OrderDetails" .Connection = sqlConn End With ' Заполнить DataSet возвращенными данными .Fill(hierDS, "Details") End With ' Установить связь между двумя таблицами … ' Найти последнюю строку в таблице Orders orderRow = hierDS.Tables("Orders").Rows. _ Item(hierDS.Tables("Orders").Rows.Count - 1) ' Удалить строку из таблицы Orders. В результате автоматически ' удаляются соответствующие дочерние строки из таблицы ' Details в DataSet. orderRow.Delete() … ' Синхронизировать изменения с источником данных sqlDAOrder.Update(hierDS, "Orders") Catch E As Exception ' Обработать исключение Finally ' Выполнить очистку End Try
|