Практическое руководство. Сохранение изменений набора данных в базе данных
После того, как данные в наборе данных были изменены и проверены, возможно, потребуется отправить обновленные данные обратно в базу данных. Для отправки измененных данных в базу данных вызовите метод Update объекта TableAdapter или адаптера данных. Метод Update адаптера обновляет одну таблицу с данными и выполнит корректную команду (INSERT, UPDATE или DELETE) в зависимости отRowState каждой строки данных в таблице.
При сохранении данных в связанных таблицах Visual Studio предоставляет новый компонент — TableAdapterManager, который помогает выполнять сохранение в правильном порядке в зависимости от ограничений внешнего ключа, определенных в базе данных. Дополнительные сведения см. в разделе Общие сведения об иерархическом обновлении.
Примечание
Так как попытка обновления источника данных содержимым набора данных может вызвать ошибки, следует вставлять код, который вызывает метод Update адаптера внутри блока try/catch.
Сама процедура обновления источника данных может варьироваться в зависимости от поставленных задач, но в любом случае приложение должно включать следующие этапы:
Выполните код, делающий попытку отправить обновления в базу данных в пределах блока try catch.
При возникновении исключения найдите строку данных, которая его вызвала. Дополнительные сведения см. в разделе Практическое руководство. Поиск строк с ошибками.
Устраните ошибку в строке данных (по возможности программно или путем предложения пользователю отредактировать ошибочную строку), затем повторите попытку обновления (свойство HasErrors, метод GetErrors).
Сохранение данных в базе данных
Вызовите метод Update объекта TableAdapter или адаптера данных, передав имя таблицы, которая содержит значения для записи в базу данных. Дополнительные сведения о сохранении данных из одиночной таблицы в базу данных содержатся в разделе Пошаговое руководство. Сохранение данных в базе данных (одна таблица).
Обновление базы данных с помощью набора данных с использованием TableAdapter
Заключите метод TableAdapter.Update в блок try / catch. В следующем примере показана попытка обновления содержимым таблицы Customers в NorthwindDataSet.
Try Me.Validate() Me.CustomersBindingSource.EndEdit() Me.CustomersTableAdapter.Update(Me.NorthwindDataSet.Customers) MsgBox("Update successful") Catch ex As Exception MsgBox("Update failed") End Try
try { this.Validate(); this.customersBindingSource.EndEdit(); this.customersTableAdapter.Update(this.northwindDataSet.Customers); MessageBox.Show("Update successful"); } catch (System.Exception ex) { MessageBox.Show("Update failed"); }
Для обновления базы данных с помощью набора данных с использованием адаптера данных:
Заключите метод DataAdapter.Update в блок try / catch. В следующем примере показана попытка обновления источника данных содержимым таблицы Table1 в DataSet1.
Try SqlDataAdapter1.Update(Dataset1.Tables("Table1")) Catch x As Exception ' Error during Update, add code to locate error, reconcile ' and try to update again. End Try
try { SqlDataAdapter1.Update(Dataset1.Tables["Table1"]); } catch (Exception e) { // Error during Update, add code to locate error, reconcile // and try to update again. }
Обновление двух связанных таблиц в наборе данных
При обновлении связанных таблиц в наборе данных важно выполнять его в правильной последовательности, чтобы снизить возможность нарушения ограничений целостности на уровне ссылок. Порядок выполнения команды будет также зависеть от индексов DataRowCollection в наборе данных. Чтобы предотвратить возникновение ошибок, связанных с целостностью данных, рекомендуется обновлять базу данных в следующей последовательности:
Дочерняя таблица: удаление записей.
Родительская таблица: вставка, обновление и удаление записей.
Дочерняя таблица: вставка и обновление записей.
Подробные сведения о сохранении данных из нескольких таблиц содержатся в разделе Пошаговое руководство. Сохранение данных в базе данных (несколько таблиц).
При обновлении двух или более связанных таблиц следует включить всю логику обновления в транзакцию. Транзакция — это процесс, гарантирующий, что все взаимосвязанные изменения в базе данных будут успешными вплоть до фиксации изменений. Дополнительные сведения см. в разделе Транзакции и параллелизм (ADO.NET).
Для обновления двух связанных таблиц с помощью TableAdapter:
Создайте три временных таблицы DataTable для хранения различных записей.
Вызовите метод Update для каждого подмножества строк из блока try/catch. При возникновении ошибки должен выполняться предлагаемый ниже порядок действий для ее разрешения.
Передача изменений из набора данных в базу данных.
Удалите временные таблицы данных для освобождения системных ресурсов.
Private Sub UpdateDB() Dim deletedChildRecords As NorthwindDataSet.OrdersDataTable = CType(NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Deleted), NorthwindDataSet.OrdersDataTable) Dim newChildRecords As NorthwindDataSet.OrdersDataTable = CType(NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Added), NorthwindDataSet.OrdersDataTable) Dim modifiedChildRecords As NorthwindDataSet.OrdersDataTable = CType(NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Modified), NorthwindDataSet.OrdersDataTable) Try If deletedChildRecords IsNot Nothing Then OrdersTableAdapter.Update(deletedChildRecords) End If CustomersTableAdapter.Update(NorthwindDataSet.Customers) If newChildRecords IsNot Nothing Then OrdersTableAdapter.Update(newChildRecords) End If If modifiedChildRecords IsNot Nothing Then OrdersTableAdapter.Update(modifiedChildRecords) End If NorthwindDataSet.AcceptChanges() Catch ex As Exception MessageBox.Show("An error occurred during the update process") ' Add code to handle error here. Finally If deletedChildRecords IsNot Nothing Then deletedChildRecords.Dispose() End If If newChildRecords IsNot Nothing Then newChildRecords.Dispose() End If If modifiedChildRecords IsNot Nothing Then modifiedChildRecords.Dispose() End If End Try End Sub
void UpdateDB() { NorthwindDataSet.OrdersDataTable deletedChildRecords = (NorthwindDataSet.OrdersDataTable)northwindDataSet.Orders.GetChanges(DataRowState.Deleted); NorthwindDataSet.OrdersDataTable newChildRecords = (NorthwindDataSet.OrdersDataTable)northwindDataSet.Orders.GetChanges(DataRowState.Added); NorthwindDataSet.OrdersDataTable modifiedChildRecords = (NorthwindDataSet.OrdersDataTable)northwindDataSet.Orders.GetChanges(DataRowState.Modified); try { if (deletedChildRecords != null) { ordersTableAdapter.Update(deletedChildRecords); } customersTableAdapter.Update(northwindDataSet.Customers); if (newChildRecords != null) { ordersTableAdapter.Update(newChildRecords); } if (modifiedChildRecords != null) { ordersTableAdapter.Update(modifiedChildRecords); } northwindDataSet.AcceptChanges(); } catch (Exception ex) { MessageBox.Show("An error occurred during the update process"); // Add code to handle error here. } finally { if (deletedChildRecords != null) { deletedChildRecords.Dispose(); } if (newChildRecords != null) { newChildRecords.Dispose(); } if (modifiedChildRecords != null) { modifiedChildRecords.Dispose(); } } }
Для обновления двух связанных таблиц с помощью адаптера данных:
Вызовите метод Update каждого адаптера данных.
Следующий пример показывает, как обновить источник данных с помощью набора данных, содержащего связанные таблицы. Чтобы выполнить последовательность, приведенную выше, создаются три временные таблицы DataTable для хранения отличающихся записей. Затем будет вызван метод Update для каждого подмножества строк из блока try catch. При возникновении ошибки должен выполняться предлагаемый ниже порядок действий для ее разрешения. Затем с помощью набора данных вносятся изменения. Наконец, происходит удаление временных таблиц данных для освобождения системных ресурсов.
Private Sub UpdateDB() Dim DeletedChildRecords As DataTable = dsNorthwind1.Orders.GetChanges(DataRowState.Deleted) Dim NewChildRecords As DataTable = dsNorthwind1.Orders.GetChanges(DataRowState.Added) Dim ModifiedChildRecords As DataTable = dsNorthwind1.Orders.GetChanges(DataRowState.Modified) Try If Not DeletedChildRecords Is Nothing Then daOrders.Update(DeletedChildRecords) End If daCustomers.Update(dsNorthwind1, "Customers") If Not NewChildRecords Is Nothing Then daOrders.Update(NewChildRecords) End If If Not ModifiedChildRecords Is Nothing Then daOrders.Update(ModifiedChildRecords) End If dsNorthwind1.AcceptChanges() Catch ex As Exception ' Update error, resolve and try again Finally If Not DeletedChildRecords Is Nothing Then DeletedChildRecords.Dispose() End If If Not NewChildRecords Is Nothing Then NewChildRecords.Dispose() End If If Not ModifiedChildRecords Is Nothing Then ModifiedChildRecords.Dispose() End If End Try End Sub
void UpdateDB() { System.Data.DataTable DeletedChildRecords = dsNorthwind1.Orders.GetChanges(System.Data.DataRowState.Deleted); System.Data.DataTable NewChildRecords = dsNorthwind1.Orders.GetChanges(System.Data.DataRowState.Added); System.Data.DataTable ModifiedChildRecords = dsNorthwind1.Orders.GetChanges(System.Data.DataRowState.Modified); try { if (DeletedChildRecords != null) { daOrders.Update(DeletedChildRecords); } if (NewChildRecords != null) { daOrders.Update(NewChildRecords); } if (ModifiedChildRecords != null) { daOrders.Update(ModifiedChildRecords); } dsNorthwind1.AcceptChanges(); } catch (Exception ex) { // Update error, resolve and try again } finally { if (DeletedChildRecords != null) { DeletedChildRecords.Dispose(); } if (NewChildRecords != null) { NewChildRecords.Dispose(); } if (ModifiedChildRecords != null) { ModifiedChildRecords.Dispose(); } } }
См. также
Основные понятия
Новые возможности разработки приложений для работы с данными
Привязка элементов управления Windows Forms к данным в Visual Studio
Привязка элементов управления к данным в Visual Studio
Другие ресурсы
Пошаговые руководства работы с данными
Подключение к данным в Visual Studio
Подготовка приложения к получению данных