Исходный код.Проект FillDataSetWithSqIDataAdapter размещен в подкаталоге, соответствующем главе 22.
Обновление базы данных с помощью объекта адаптера данных
Адаптеры данных могут не только заполнять для вас таблицы объекта DataSet. Они могут также поддерживать набор объектов основных SQL-команд, используя их для возвращения модифицированных данных обратно в хранилище данных. При вызове метода Update() адаптера данных проверяется свойство RowState для каждой строки в DataTable и используются соответствующие SQL-команды, присвоенные свойствам DeleteCommand, InsertCommand и UpdateCommand, чтобы записать изменения данного DataTable в источник данных.
Чтобы проиллюстрировать процесс использования адаптера данных для возвращения изменении DataTable в хранилище данных, в следующем примере мы переработаем приложение CarsInventoryUpdater, созданное в этой главе ранее, чтобы на этот раз использовать DataSet и объект адаптера данных. Поскольку значительная часть приложения останется той же, сконцентрируем свое внимание на изменениях, которые необходимо сделать в методах DeleteCar(). UpdateCarPetName() и InsertNewCar() (чтобы уточнить детали, проверьте текст загружаемого программного кода для данного примера).
Первым основным изменением, которое требуется внести в приложение, является определение двух новых статических членов-переменных класса Program для представления DataSet и объекта соединения. Также, чтобы заполнить DataSet начальными данными, модифицируется метод Main().
class Program {
// Объект DataSet, доступный на уровне приложения.
public static DataSet dsСarInventory = new DataSet("CarsDatabase");
// Объект соединения, доступный на уровне приложения.
public static SqlConnection cnObj = new SqlConnection("uid-sa;pwd=;Initial Catalog=Cars;Data Source= (local)");
static void Main(string[] args) {
// Создание адаптера данных и заполнение DataSet.
SqlDataAdapter dAdapter = new SqlDataAdapter("Select * From Inventory", chObj);
dAdapter.Fill(dsCarInventory, "Inventory");
ShowInstructions();
// Программный код получения команды пользователя…
}
…
}
Обратите внимание и на то, что методы ListInventory(), DeleteCar(), UpdateCarPetName() и InsertNewCar() также были изменены с тем, чтобы они могли принять SqlDataAdapter в качестве параметра.
Установка свойства InsertCommand
При использовании адаптера данных для обновления DataSet первой задачей оказывается назначение свойствам UpdateCommand, DeleteCommand и InsertCommand действительных объектов команд (пока вы этого не сделаете, эти свойства возвращают null). Слово "действительные" для объектов команд здесь используется потому, что набор объектов команд, которые вы "подключаете" к адаптеру данных, изменяется в зависимости от таблицы, данные которой вы пытаетесь обновить. В этом примере соответствующей таблицей является таблица Inventory. И вот как выглядит измененный метод InsertNewCar().
private static void InsertNewCar(SqlDataAdapter dAdapter) {
// Сбор информации о новой машине.
…
// Формирование SQL-оператора Insert и подключение к DataAdapter.
string sql = string.Format("Insert Into Inventory" +
"(CarID, Make, Color, PetName) Values" +
"('{0}', '{1}', '{2}', '{3}')",
newCarID, newCarMake, newCarColor, newCarPetName);
dAdapter.InsertCommand = new SqlCommand(sql);
dAdapter.InsertCommand.Connection = cnObj;
// Обновление таблицы Inventory с учетом новой строки.
DataRow newCar = dsCarInventory.Tables["Inventory"].NewRow();
newCar["CarID"] = newCarID;
newCar["Make"] = newCarMake;
newCar["Color"] = newCarColor;
newCar["PetName"] = newCarPetName;
dsCarInventory.Tables["Inventory"].Rows.Add(newCar);
dAdapter.Update(dsCarInventory.Tables["Inventory"]);
}
После создания объекта команды он "подключается" к адаптеру с помощью свойства InsertCommand. Затем в DataTable таблицы Inventory добавляется новая строка, представленная объектом dsCarInventory. После добавления DataRow в DataTable адаптер выполнит SQL-команду, обнаруженную в свойстве InsertCommand, поскольку значением RowState этой новой строки является DataRowState.Added.
Установка свойства UpdateCommand
Модификации метода UpdateCarPetName() оказываются приблизительно такими же. Просто создайте новый объект команды и укажите его для свойства UpdateCommand.
private static void UpdateCarPetName(SqlDataAdapter dAdapter) {
// Сбор информации об изменяемой машине.
…
// Форматирование SQL-оператора Update и подключение к DataAdapter.
string sql = string.Format("Update Inventory Set PetName = '{0}' Where CarID = '{1}'", newPetName, carToUpdate);
SqlCommand cmd = new SqlCommand(sql, cnObj);
dAdapter.UpdateCommand = cmd;
DataRow[] carRowToUpdate = dsCarInventory.Tables["Inventory"].Select(string.Format("CarID = '{0}'", carToUpdata));
Читать дальше