Architecture Net или что такое Microsoft.NET?




Изменение объекта DataRow

При необходимости внести значительные изменения в объект DataSet (Набор данных) и отложить при этом проверку ограничений и событий, можно использовать режим редактирования набора данных.

BeginEdit. EndEdit, CancelEdit

Переход в режим редактирования осуществляется вызовом метода BeginEdit объекта строки, которую необходимо изменить. Для выхода из этого режима используются методы EndEdit и CancelEdit.
В примере DataEditing мы нарушаем ограничение, заданное внешним ключом, добавляя в таблицу Books (Книги) строку, описывающую книгу автора, идентификатор которого отсутствует в базе данных. Исключение, являющееся результатом этого нарушения, возникнет только после вызова метода EndEdit. Так, при выполнении следующего фрагмента файла DataEditing. h примера DataEditing исключение не возникает.

DataRow *rowToEdit = books->Rows->get_Item(0); // книги-> Строки
rowToEdit->BeginEdit();
try
{
rowToEdit->set_Item("Author!d", _box(21));
}
catch(Exception *e) // Исключение
{
Console::WriteLine(
"\n {0] while editing a row.", e->Message); // при редактировании строки, Сообщение); Console::WriteLine(); }

Однако исключение возникает, как только в программе вызывается метод EndEdit.

try {
rowToEdit->EndEdit(); }
catch(Exception *e) // Исключение {
Console::WriteLine();
Console::WriteLine(
"\n{0} on EndEdit", e->Message); // Сообщение
Console::WriteLine(); }

В результате будет напечатано следующее сообщение, указывающее на то, что по окончании сеанса изменения содержимого строки обнаружено нарушение ограничения.
ForeignKeyConstraint Authors->Books requires the child key values (21) to exist in the parent table, on EndEdit

Версии объекта DataRow

До того, как будут подтверждены внесенные в строку изменения, доступны и исходные, и измененные значения полей строки. С помощью свойства элемента строки28 Da-taRowVersion можно определить, какое именно значение вы хотите использовать. Это свойство может иметь значения Original (Первоначальное), Default (Заданное по умолчанию), Current (Текущее) и Proposed (Предложенное).
В следующем фрагменте примера DataEditing приведен код, выполняющийся до вызова метода EndEdit:

DataRow *rowToEdit = books->Rows->get_Item(0);
// книги-> Строки rowToEdit->BeginEdit() ; try {
rowToEdit->set_Item("AuthorId", _box(21)); Console::WriteLine(
"Book Author Id Field Current Value {0}",
// Текущее значение поля идентификатора автора книги
rowToEdit->get_Item(
"Authorld", DataRowVersion::Current)); Console::WriteLine(
"Book Author Id Field Proposed Value {0}",
// Предложенное значение поля идентификатора автора книги
rowToEdit->get_Item(
"Authorld", DataRowVersion::Proposed)); // Предложенное Console::WriteLine(
"Book Author Id Field Default Value {0}",
// Значение по умолчанию поля идентификатора автора книги
rowToEdit->get_Item(
"Authorld", DataRowVersion::Default));
// Значение по умолчанию }

В результате программа напечатает:

Book Author Id Field Current Value I Book Author Id Field Proposed Value 21 Book Author Id Field Default Value 21

Вот перевод:

Текущее значение поля идентификатора автора книги 1
Предложенное значение поля идентификатора автора книги 21
Значение по умолчанию поля идентификатора автора книги 21

При выполнении транзакционного редактирования доступны значения Current (Текущее) и Proposed (Предложенное). После вызова метода CancelEdit значение Proposed (Предложенное) становится недоступным. После вызова метода EndEdit значение, имевшее атрибут Proposed (Предложенное) меняет атрибут на Current (Текущее) а значение, имевшее атрибут Proposed (Предложенное), становится недоступным.

Свойство RowState объекта DataRow

Кроме того, что в режиме редактирования доступны значения поля Current (Текущее) и Proposed (Предложенное), сам объект DataRow имеет свойство, описывающее состояние соответствующей строки. Это свойство может принимать значения Added (Добавлено), Deleted (Удалено), Detached (Отсоединено), Modified (Изменено) или Unchanged (He изменено).
Строка находится в состоянии Detached (Отсоединено) в случаях, когда она создана, но либо еще не добавлена ни в одну коллекцию объектов DataRow, либо удалена из какой-нибудь коллекции.
Какое из значений будет возвращено при использовании значения Default (Заданное по умолчанию) свойства DataRowVersion определяется значением свойства RowState.

Принятие или отмена изменений

Вызов метода EndEdit объекта DataRow не приводит к фиксации изменений, сделанных в строке. Вызов методов AcceptChanges или RejectChanges объектов DataSet (Набор данных), DataTable (Таблица данных) или DataRow приводит к выходу из режима транзакционного редактирования для всех строк соответствующего объекта. Если до этого не были вызваны EndEdit или CancelEdit, AcceptChanges или Rejec-tChanges вызывают эти методы для всех строк соответствующего объекта.
После вызова метода AcceptChanges значения, имевшие атрибут Proposed (Предложенное) становятся основными (т.е. имеющими атрибут Original (Первоначальное)). Если при этом свойство RowState имело значение Added (Добавлено), Modified (Изменено) или Deleted (Удалено), ему присваивается значение Unchanged (He изменено), а сами изменения вступают в силу (т.е. строки добавляются, изменяются или удаляются).
После выполнения метода RejectChanges значение, имевшее атрибут Proposed (Предложенное), удаляется. Если при этом свойство RowState имело значение Deleted (Удалено) или Modified (Изменено), значение поля становится прежним и свойству RowState присваивается значение Unchanged (He изменено). Если же RowState имело значение Added (Добавлено), строка удаляется из коллекции Rows (Строки).
Так как после вызова метода AcceptChanges свойство RowState имеет значение Unchanged (He изменено), вызов метода Update (Обновить) объекта DataAdapter не приведет к каким-либо изменениям базы данных. Поэтому, при необходимости внести изменения в базу данных, метод Update (Обновить) следует вызывать до вызова метода AcceptChanges строки, таблицы или объекта DataSet (Набор данных).
Ниже приведен фрагмент реализации метода CancelReservation класса HotelBroker (Посредник, бронирующий места в гостинице) из примера CaseStudy. Фрагмент взят из файла HotelBookings . h, находящегося в папке CaseStudy\HotelBrokerAdmin\Hotel. Обратите внимание, что метод AcceptChanges объекта DataSet (Набор данных) вызывается при успешном завершении работы метода SqlDataAdapter: : Update (Обновить). В случае же возникновения исключения вызывается метод RejectChanges.

void CancelReservation(int id) // идентификатор
{
DataTable *t = 0;
try
{
t = dataset->Tables->get_Item("Reservations");
// набор данных-> Таблицы-> get_Item ("Резервирование");
DataRow *rc [] = t->Select ( // Выбор
String::Format("Reservationld = {0} ", // Строка:: Формат
id.ToString())); // идентификатор for (int i=0; i<rc->Length; i++) re[i]->Delete(); // Удалить
int NumberRows = adapter->Update( // Обновление dataset, "Reservations"); // набор данных, "Резервирование"); if (NumberRows > 0) // если (NumberRows> 0)
t->AcceptChanges () ; else
t->RejectChanges () ; }
catch(Exception *e) // Исключение {
t->RejectChanges();
throw e; }
return;
}

Если вы не будете отменять внесенные изменения в случае возникновения ошибки, измененные строки останутся в объекте DataSet (Набор данных). Тогда, при попытке произвести следующее обновление, оно также будет отменено из-за того, что строки все еще не обновлены и наличие их приводит к возникновению исключения. Поскольку объект DataSet (Набор данных) независим от других баз данных, тот факт, что данные в базе данных были обновлены, не имеет никакого отношения к принятию или отмене произведенных изменений данных в самом объекте DataSet (Набор данных).

Ошибки объекта DataRow

Если при изменении данных строки произошла ошибка, свойство HasError объекта DataSet (Набор данных), DataTable (Таблица данных) или DataRow примет значение true (истина). Для получения информации об ошибке используются методы GetCol-umnError или GetCoiunmsInError.