Страница 6 из 8 ОбновленияПри обновлениях строк в связанных таблицах должна сохраняться целостность данных. Для обеспечения ссылочной целостности дочерняя строка должна ссылаться на допустимую строку в родительской таблице. При этом можно использовать каскадное обновление. Автоматическая генерация команды UpdateИзменения передаются источнику данных после обновления строки в таблице объекта DataSet и вызова метода Update объекта DataAdapter. Последний автоматически генерирует команду Update на основе предоставленной вами команды Select. В следующем примере кода мы переносим позиции из одного заказа в другой, демонстрируя, как осуществляется каскадное обновление. Dim sqlConn As SqlConnection Dim sqlDAOrder As SqlDataAdapter Dim sqlDADetail As SqlDataAdapter Dim sqlCmdBldrDetail As SqlCommandBuilder Dim hierDS As DataSet Try ' Создать новое соединение sqlConn = New SqlConnection(Common.getConnectionString) ' Создать новый объект SqlDataAdapter для таблицы Order sqlDAOrder = New SqlDataAdapter() ' Создать новый объект SqlDataAdapter для таблицы OrderDetails sqlDADetail = New SqlDataAdapter() ' Создать новый DataSet hierDS = New DataSet() ' Создать новый объект SQLCommandBuilder, автоматически формирующий ' команды Update sqlCmdBldrDetail = New SqlCommandBuilder(sqlDADetail) With sqlDAOrder ' Добавить объект SelectCommand .SelectCommand = New SqlCommand() ' Указать команду Select With .SelectCommand .CommandType = CommandType.Text .CommandText = "Exec GetOrderHeader @OrderId=2" .Connection = sqlConn End With ' Заполнить DataSet возвращенными данными .Fill(hierDS, "Orders") End With With sqlDADetail ' Добавить объект SelectCommand .SelectCommand = New SqlCommand() ' Указать команду Select With .SelectCommand .CommandType = CommandType.Text .CommandText = "Exec GetOrderDetails @OrderId=2" .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")) hierDS.Tables("Orders").Columns("OrderId").ReadOnly = False ' Перенести позиции из одного заказа в другой orderRow = hierDataSet.Tables("Orders").Rows(0) orderRow("OrderId") = 1 ' Синхронизировать изменения sqlDADetail.Update(hierDS, "Details") Catch E As Exception ' Обработать исключение Finally ' Выполнить очистку End Try
Использование свойства UpdateCommandАвтоматически сформированная команда перемещала каждую строку за одно обращение к базе данных, а хранимая процедура могла бы переместить за одно обращение все строки. Чтобы указать собственное выражение Update, исполняемое при вызове метода Update применительно к DataAdapter, задайте свойство UpdateCommand. Его значением может быть параметризированный запрос или хранимая процедура. Параметры UpdateCommand определяются так же, как и параметры объекта Command. Dim sqlConn As SqlConnection Dim sqlDAOrder As SqlDataAdapter Dim sqlDADetail As SqlDataAdapter Dim hierDS As DataSet Try ' Создать новое соединение 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.Text .CommandText = "Exec GetOrderHeader @OrderId=1" .Connection = sqlConn End With ' Добавить объект UpdateCommand .UpdateCommand = New SqlCommand() ' Указать команду Update With .UpdateCommand .CommandType = CommandType.StoredProcedure .CommandText = "MoveOrderDetails" ' Указать параметры .Parameters.Add(New SqlParameter("@FromOrderId", SqlDbType.Int)) .Parameters("@FromOrderId").Direction = ParameterDirection.Input .Parameters("@FromOrderId").SourceColumn = "OrderId" .Parameters("@FromOrderId").SourceVersion = _ DataRowVersion.Original .Parameters.Add(New SqlParameter("@ToOrderId", SqlDbType.Int)) .Parameters("@ToOrderId").Direction = ParameterDirection.Input .Parameters("@ToOrderId").SourceColumn = "OrderId" .Parameters("@ToOrderId").SourceVersion = DataRowVersion.Current .Connection = sqlConn End With ' Заполнить DataSet возвращенными данными .Fill(hierDS, "Orders") End With With sqlDADetail ' Добавить объект SelectCommand sqlDADetail.SelectCommand = New SqlCommand() ' Указать команду Select With .SelectCommand .CommandType = CommandType.Text .CommandText = "Exec GetOrderDetails @OrderId=1" .Connection = sqlConn End With ' Заполнить DataSet возвращенными данными .Fill(hierDS, "Details") End With ' Установить между двумя таблицами отношение через внешний ключ hierDataSet.Relations.Add("Order_Detail", _ hierDS.Tables("Orders").Columns("OrderId"), _ hierDS.Tables("Details").Columns("OrderId")) hierDS.Tables("Orders").Columns("OrderId").ReadOnly = False ' Перенести позиции из одного заказа в другой orderRow = hierDS.Tables("Orders").Rows(0) orderRow("OrderId") = 2 ' Синхронизировать изменения sqlDAOrder.Update(hierDS, "Orders") Catch E As Exception ' Обработать исключение Finally ' Выполнить очистку End Try
Свойство SourceVersion позволяет передавать исходное и текущее значение OrderId в соответствующие параметры хранимой процедуры. |