ADO.NET. Управление базами данных. Связь по схеме OLE DB провайдера. Коррекция стилей DataGridView, страница 6

·  Перенесите в класс формы объявление четырех объектов ADO.NET, которые ранее были временными переменными, живущими только в обработчике события Load. Теперь их следует помнить, так как они понадобятся в обработчиках событий (например для обработки нажатия кнопки Save).

  DataSet ds;

  OleDbConnection cn;

  OleDbDataAdapter da;

·  Внесите изменения в MainForm_Load так, чтобы она приобрела вид:

//==== Создание объектов ADO.NET

ds = new DataSet (); 

cn = new OleDbConnection (

  @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=..\..\Data\Students.MDB");

da = new OleDbDataAdapter("Select * from Studs", cn); // Другой способ создать Адаптер

//==== Создание построителя, который автоматизирует процесс создания команд (Insert, Delete и Update)

OleDbCommandBuilder builder = new OleDbCommandBuilder (da);

Console.WriteLine ("\n" + builder.GetUpdateCommand().CommandText);

da.Fill (ds, "Studs");

AddStyle();

gridStud.DataSource = ds;

gridStud.DataMember = ds.Tables[0].TableName;

Как видите, теперь постоянные, а не временные (локальные) объекты: ds, cn, cmd, da, созданы, инициализированы и используются для заполнения DataSet. Логика создания и инициализации объектов немного изменилась, мы обошлись без объекта OleDbCommand. Адаптер создал его за нас.

Для автоматической генерации трех команд обновления данных пользуемся услугами нового класса из семейства ADO.NET — OleDbCommandBuilder. Чтобы увидеть, как он работает, в тело метода обработки нажатий кнопок навигатора введите следующий код:

case "&Save": UpdateDB (); break;

Создайте с помощью механизма Intellisense заготовку метода UpdateDB и вставьте в него следующий код.

try { da.Update (ds.Tables[0]); }

catch (Exception ex) { MessageBox.Show (ex.Message); }

Теперь при каждом нажатии кнопки Save будут выполняться следующие действия. Для каждой измененной строки таблицы, которая выбрана из DataSet (см. код ds.Tables[0]), метод Update класса OleDbDataAdapter выполнит одну из команд: INSERT, DELETE или UPDATE. Тип команды зависит от текущего состояния строки. Сами команды генерируются построителем команд (OleDbCommandBuilder).

Здесь есть тонкий момент — построитель один раз генерирует логику работы с базой данных и более не реагирует на изменения команды Select. Если вы в ходе программы изменили текст команды Select, то необходимо заставить построитель заново создать остальные три команды обновления данных. Для этой цели построитель имеет метод RefreshSchema.

Построитель начинает работать в момент выполнения команд INSERT, DELETE или UPDATE. Он работает с драйвером СУБД и для каждой обновляемой строки имитирует логику обновления ADO (это предыдущая, основанная на COM, технология). Поэтому построитель работает неэффективно. Странным является факт, что команды, созданные построителем, не попадают в свойства адаптера: da.InsertCommand, da.DeleteCommand и da.UpdateCommand. Проверьте в режиме отладки значения этих свойств — все они равны null.

Странно и то, что построитель можно включить такой командой: new OleDbCommandBuilder(da);. Здесь ссылка, возвращаемая операцией new, не запоминается в переменной builder. Создается впечатление, что объект никому не нужен. На самом деле построитель включился и ждет момента обновления, когда ему придется работать.

Заметим, что существует альтернативный способ обновления данных — не использовать построитель, а создать вручную три объекта типа OleDbCommand (для трех комманд Insert, Delete и Update) и запомнить их в свойствах адаптера InsertCommand и т. д. Этот способ требует некоторой квалификации программиста, но он дает более эффективный код. Этим способом пользуется также типизированный DataSet, который создает мастер студии на основе схемы, или файла БД (например, xsd, mdf или mdb).

Для того, чтобы увидеть хотя бы одну из команд, которые построитель будет использовать в момент обновления данных, мы вставили оператор вывода на консоль, который выводит текст команды UPDATE.