Операции над данными с иерархической структурой. Разработка распределенных приложений в .NET
Страница 6. Обновления


 

Обновления

При обновлениях строк в связанных таблицах должна сохраняться целостность данных. Для обеспечения ссылочной целостности дочерняя строка должна ссылаться на допустимую строку в родительской таблице. При этом можно использовать каскадное обновление.

Автоматическая генерация команды 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 в соответствующие параметры хранимой процедуры. 

 
« Предыдущая статья   Следующая статья »