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

·  Перед тем, как добавить новую строку в таблицу экзаменов несколько раз переведите фокус в последнюю, пустую строку DataGridView и верните его в какую-либо предыдущую, заполненную строку. Понаблюдайте за значениями поля ExamID. Тот же опыт проведите с пустой строкой таблицы студентов.

Работая в отсоединенном режиме, DataSet накапливает изменения в обеих таблицах. Измененные таблицы DataSet содержат добавления в таблицу студентов и в таблицу экзаменов. В них также есть строки, которые помечены, как удаляемые. Их надо удалить из базы данных.

Проблема состоит в том, что последовательный вызов метода Update (сначала для таблицы студентов, а затем для таблицы экзаменов) не может внести изменения, не нарушив ограничения целостности по ссылкам (referential integrity constraints), которые следят за тем, чтобы все экзамены имели ссылки на существующих студентов. Удалив строки некоторых студентов, мы нарушим целостность по ссылкам, так как в подчиненной таблице останутся их экзамены. Если поменять порядок следования операций Update, то это не решит проблемы, так как добавленные экзамены будут ссылаться на несуществующих студентов.

Как решать проблему целостности по ссылкам? Добавления новых строк следует производить в порядке сверху-вниз, а удаления в порядке снизу-вверх. Говоря сверху-вниз, мы подразумеваем направление от главных таблиц к подчиненным. Если связь между таблицами имеет вид 1-оо (один ко многим), то сначала надо добавить строку на стороне 1, а затем на стороне оо. Удалять строки надо в обратном порядке.

Как решать проблему автоинкрементируемых ключей? После внесения добавлений обращаться к базе, узнавать новые значения первичных ключей и изменять соответствующие им foreign keys в подчиненных таблицах. Опишем порядок внесения изменений в таблицы студентов и экзаменов, который должен привести к успеху.

·  Добавить новых студентов  (INSERT), и узнать значения StudID, присвоенных им драйвером базы данных,

·  Изменить значения связанных ключей в строках таблицы экзаменов, соответствующих новым студнтам,

·  Произвести добавления в данные таблицы экзаменов (INSERT),

·  Произвести изменения в данных таблицы студентов (UPDATE),

·  Произвести изменения в данных таблицы экзаменов (UPDATE),

·  Произвести удаления в данных таблицы экзаменов (DELETE),

·  Произвести удаления в данных таблицы студентов (DELETE),

Здесь важен порядок добавления новых строк (сначала в главную таблицу, затем в подчиненную) и порядок удаления строк (сначала в подчиненной таблице, затем в главной). Порядок обновления (UPDATE) строк менее важен. В первом приближении (по совету David Sceppa, автора книги Microsoft ADO.NET) можно использовать такой алгоритм внесения изменений в базу данных.

void UpdateDB()

  {

   try

   {

    bsStuds.EndEdit();

    bsExams.EndEdit();

    DataTable

      studs = ds.Tables[0],

      exams = ds.Tables[1];

    daStud.Update(studs.Select("", "", DataViewRowState.Added));

    daExam.Update(exams.Select("", "", DataViewRowState.Added));

    daStud.Update(studs.Select("", "", DataViewRowState.ModifiedCurrent));

    daExam.Update(exams.Select("", "", DataViewRowState.ModifiedCurrent));

    daExam.Update(exams.Select("", "", DataViewRowState.Deleted));

    daStud.Update(studs.Select("", "", DataViewRowState.Deleted));

   }

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

  }

Команда Select используется для выделения типов изменений в зависимости состояния строк. Добавления производятся в порядке сверху-вниз, а удаления — снизу-вверх. Приведенный алгоритм работает более предсказуемо, но он тоже дает сбои.