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

ОГЛАВЛЕНИЕ

 

Обновления

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

Автоматическая генерация команды 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