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

С помощью IntelliSense ведите реакцию на событие RowUpdated, поддерживаемое адаптером.

da.RowUpdated += new OleDbRowUpdatedEventHandler (da_RowUpdated);

Новый делегат (имеющий задание da_RowUpdated) и ссылка на него добавляется в коллекцию делегатов события RowUpdated адаптера da. Обработчик события автоматически создается редактором студии, если вы вовремя (и дважды) нажали клавишу TAB. В обработчик события вставьте следующий код.

void da_RowUpdated (object sender, OleDbRowUpdatedEventArgs e)

{

  OleDbCommand cmd = new OleDbCommand ("SELECT @@IDENTITY", e.Command.Connection);

  e.Row["StudID"] = cmd.ExecuteScalar();

  e.Row.AcceptChanges();   // Позже эта установка произойдет автоматически

}

Теперь после каждого обновления таблицы в памяти (не в базе, это-то и плохо) будет выполняться SQL-запрос, который возвращает значение первичного ключа, сгенерированного СУБД. Такая трактовка метода ExecuteScalar определяется синтаксисом команды SELECT @@IDENTITY. Она не работает в Access 2000 и ниже. Протестируйте работу приложения, повторите наш опыт и убедитесь, что все стало работать лучше, за исключением сообщения, носящего информационный характер. Для того, чтобы убрать эту помарку, измените код обработчика события RowUpdated.

if (e.Status == UpdateStatus.Continue && e.StatementType == StatementType.Insert)

{

  e.Row["StudID"] = (int) (new OleDbCommand("SELECT @@IDENTITY", cn)).ExecuteScalar();

  e.Row.AcceptChanges();   // Позже эта установка произойдет автоматически

}

Объясните изменения значений первичного ключа, которые наблюдаются при многократном переводе фокуса из новой, последней строки (она называется AddRow) в старую и назад. После обновления этот нестабильный индекс корректируется и становится равным тому, что присвоил Access. Можно-ли избавиться от нестабильности? Думаю, что нет — такова логика работы ADO.NET с флагом MissingSchemaAction.

Состояния строк и их версии

ADO.NET построена на принципе отсоединеного режима работы. Когда пользователь изменяет данные таблиц DataSet, то изменения кешируются в дополнительных версиях строк (объектах класса DataRow), Изменения попадают в базу не сразу, а после вызова метода Update (если работа ведется с DbDataAdapter), или после вызова ExecuteNonQuery (если работа ведется с объектом вида DbCommand).

Записи таблицы (строки DataTable, или объекты DataRow) создаются в процессе ее заполнения программным способом (метод NewRow), или при загрузке данных из базы (метод Fill). Далее они проходят определенные фазы своего жизненного цикла, переходя из одного состояния в другое. Каждая строка содержит информацию о своем текущем состоянии, статусе и свойствах.

Свойство RowState класса DataRow имеет тип перечисления DataRowState, описывающего все возможные состояния строки. Оно несет информацию об изменениях строки с момента ее создания. Его легко спутать с другими: DataViewRowState (содержит перечень возможных состояний строки при работе с DataView) и DataRowVersion (перечень возможных, иногда одновременно существующих, версий строки).

Сначала рассмотрим состояния, в которых может находиться строка. Они доступны с помощью свойства RowState класса DataRow. При создании новой строки (row = dt.NewRow();) она пребывает в состоянии Detached и остается в нем, пока не попадет в DataTable (table.Rows.Add (row);). В этот момент строка переходит в состояние Added. Вспомните, что вы писали подобный код при выполнении задания (в ADO Intro1). При изменении данных строка переходит в состояние Modified. Удаленная строка в DataGridView не отображается, но остается в DataTable и переходит в состояние Deleted. Ее можно вернуть в состояние Unchanged, если вызвать метод;

row.RejectChanges();

или удалить навсегда, вызвав метод row.AcceptChanges();. Приведем перечень всех возможных состояний строки таблицы (точнее, объекта класса DataRow) с краткими пояснениями.