У меня есть около 10 таблиц, которые я загружаю в DataSet, используя один DataAdapter в последовательности. Во время загрузки я использую только один DataAdapter и заменяю имена таблиц и операторы SELECT по мере необходимости. Я заменяю имя таблицы и оператор выбора SQL и последовательно заполняю таблицы в наборе данных. Все делается внутри двух вложенных операторов «using» для удаления объектов подключения и DataAdapter, как показано ниже.
using (OleDbConnection conn = new OleDbConnection (Db.DbConnGet ())) {
using (var da = new OleDbDataAdapter (sql, conn)) {
tablename = "Table1";
da.SelectCommand.CommandText = $"Select * from {tablename}";
try {
da.Fill (hsdset, tablename);
} catch (Exception ex) {
...
}
tablename = "Table2";
da.SelectCommand.CommandText = $"Select * from {tablename}";
try {
da.Fill (hsdset, tablename);
} catch (Exception ex) {
...
}
}}
Как видите, DataAdapter удаляется после завершения загрузки, и я передаю DataSet в свое приложение по мере необходимости для чтения данных.
Но теперь мне нужно обновить или расширить данные в наборе данных и вернуть их в базу данных. Обновление DataTables внутри датасета не проблема — в сети есть много примеров. Я повторно создал новое соединение и DataAdapter, чтобы обновить таблицу в существующем, измененном, строго типизированном наборе данных следующим образом.
using (OleDbConnection conn = new OleDbConnection (Db.DbConnGet ())) {
using (var da = new OleDbDataAdapter ("", conn)) {
// this is required; I don't know if it is used by Update
da.SelectCommand.CommandText = $"Select * from " + tablename;
try {
// build special update commands from the table->db differences
var cbuilder = new OleDbCommandBuilder (da);
da.Update (dset, "Layers");
} catch (Exception ex) {
...
}
}
}
}
Мой первый вопрос: «Действительно ли операция обновления использует исходный оператор SELECT для извлечения информации из базы данных? Если нет, то зачем это нужно? Я думал, что DataSet отслеживает измененные строки, новые строки, удаленные строки и т. д. Я думал, что обновление может быть сделано без повторного чтения всей таблицы данных или, может быть, он читает только те записи, которые отмечены как измененные в DataTable?
Мой второй вопрос: каков наилучший (или нормальный) способ работы с наборами данных и адаптерами данных таким образом? Лучше всего всегда сохранять исходные адаптеры данных для последующего использования или лучше создавать новые, как я сделал выше? (Сохраняет ли исходный DataAdapter какую-либо информацию о состоянии во время загрузки, которой не было бы у вновь созданного DataAdapter?) Спасибо.
SELECT
не используется для обновления, аCommandBuilder
использует операторSELECT
для создания команд CRUD для обновления. Вопрос 2. Совершенно нормально создавать их один раз в конструкторе или при загрузке формы, а затем использовать при необходимости. Важно то, что вы должны избавиться от них перед закрытием формы. Хорошей идеей является добавление их вcomponents
контейнер формы, как это делает дизайнер, когда вы перетаскиваете компонент на форму, таким образом, компоненты будут автоматически удаляться при удалении формы. - person Reza Aghaei   schedule 22.12.2019