Опубликован: 05.08.2007 | Доступ: свободный | Студентов: 2201 / 83 | Оценка: 4.47 / 4.09 | Длительность: 20:11:00
ISBN: 978-5-9556-0097-0
Лекция 13:

Передача изменений в базу данных при помощи хранимых процедур. Объект CommandBuilder

Обновление связанных таблиц

В "Элементы работы с базами данных" , при создании схемы базы данных BDTur_firm.mdb, мы определили вложенную группу "Туры" 1 - °"Сезоны" 1 - °"Путевки" 1 - °"Оплата". Далее, при экспорте этой базы в формат Microsoft SQL получился набор отдельных таблиц - мастер преобразований не перенес связи между таблицами. Рассмотрим вывод на форму и обновление этих таблиц, связанных между собой в типизированном объекте DataSet. Программное определение всех полей и параметров заняло бы слишком много места, поэтому на этот раз будем использовать визуальные средства студии. При необходимости вы сможете самостоятельно переделать приложение - изученный материал настоящей лекции позволит вам это сделать.

Запускаем SQL Server Enterprise Manager, раскрываем узел базы BDTur_firm2 и в режиме дизайна таблиц задаем ключевые поля (рис. 13.9):

 Задание ключевых полей в SQL Server Enterprise Manager

Рис. 13.9. Задание ключевых полей в SQL Server Enterprise Manager

Создайте новое Windows-приложение и назовите его "MultiFilling AndUpdating". Свойству "Size" формы устанавливаем значение "500;300". Перетаскиваем на форму элемент управления DataGrid, его свойству Dock устанавливаем значение "Fill". Добавляем на форму элемент Panel, его свойству Dock устанавливаем значение "Bottom". На панели размещаем четыре элемента RadioButton со следующими свойствами:

radioButton1, свойство Значение
Name rbTours
Location 26; 16
Tag Туры
Text Туры
radioButton2, свойство Значение
Name rbSeasons
Location 138; 16
Tag Сезоны
Text Сезоны
radioButton3, свойство Значение
Name rbPasses
Location 250; 16
Tag Путевки
Text Путевки
radioButton4, свойство Значение
Name rbPayments
Location 362; 16
Tag Оплата
Text Оплата

Свойство "Tag" элементов RadioButton будет использоваться для задания выводимого содержимого при выборе элементов. Переходим на вкладку "Server Explorer", настраиваем подключение к базе Microsoft SQL "BDTur_firm2", из узла "Tables" перетаскиваем на форму таблицы "Туры", "Сезоны", "Путевки", "Оплата". Соответствующие объекты DataAdapter называем "daTours", "daSeasons", "daPasses" и "daPayments". Выделив любой из объектов DataAdapter, в окне его свойств нажимаем на ссылку "Generate Dataset". В появившемся окне Generate Dataset вводим название "dsBDTur_firm" и отмечаем галочками все таблицы - они будут находиться в объекте DataSet (рис. 13.10):

 Создание объекта DataSet

Рис. 13.10. Создание объекта DataSet

В результате получился типизированный объект DataSet. Переходим в окно "Solution Explorer", дважды щелкаем на файле dsBDTur_firm.xsd. В режиме дизайна XSD-схемы связываем таблицы по ключевым полям, оставляя названия связей по умолчанию2Если вы забыли, как это делается, вернитесь к пятой Главе.. Готовая схема будет иметь следующий вид (рис. 13.11):

 Готовая XSD-схема объекта dsBDTur_firm

Рис. 13.11. Готовая XSD-схема объекта dsBDTur_firm

Переходим в код формы. В конструкторе заполняем объект DataSet:

public Form1()
{
	InitializeComponent();
	//Отключаем ограничения на время заполнения объекта DataSet
	dsBDTur_firm1.EnforceConstraints = false;
	sqlConnection1.Open();
	//Заполняем объект DataSet
	daTours.Fill(dsBDTur_firm1);					
	daSeasons.Fill(dsBDTur_firm1);					
	daPasses.Fill(dsBDTur_firm1);	
	daPayments.Fill(dsBDTur_firm1);	
	sqlConnection1.Close();
	//Включаем ограничения
	dsBDTur_firm1.EnforceConstraints = true;
	//Привязываем все обработчики всех элементов RadioButton к одному 
	rbTours.CheckedChanged +=
	 new EventHandler(rbTours_CheckedChanged);
	rbSeasons.CheckedChanged +=
	 new EventHandler(rbTours_CheckedChanged);
	rbPasses.CheckedChanged +=
	 new EventHandler(rbTours_CheckedChanged);
	rbPayments.CheckedChanged +=
	 new EventHandler(rbTours_CheckedChanged);
}

Обратите внимание на порядок заполнения DataSet. Вначале поступают данные из родительских таблиц, затем из дочерних. Это позволяет не нарушать целостность записей. Создаем метод rbTours_CheckedChanged, в котором реализуем переключатель содержимого объекта DataGrid:

private void rbTours_CheckedChanged(object sender, EventArgs e)
{
	RadioButton rb = (RadioButton)sender;
	if(!rb.Checked)
	return;			
	dataGrid1.DataSource = dsBDTur_firm1;
	dataGrid1.DataMember = rb.Tag.ToString();
}

В обработчике события Closing формы передаем изменения в базу данных:

private void Form1_Closing(object sender,
 System.ComponentModel.CancelEventArgs e)
{
	try
	{
		sqlConnection1.Open();
		daTours.Update(dsBDTur_firm1);	
		daSeasons.Update(dsBDTur_firm1);
		daPasses.Update(dsBDTur_firm1);
		daPayments.Update(dsBDTur_firm1);
	}
	catch(Exception ex)
	{
		MessageBox.Show(ex.ToString());
	}
	finally
	{
		sqlConnection1.Close();
	}
}

Здесь снова вначале передаются изменения из родительских таблиц, затем из дочерних. В готовом приложении можно вставлять, изменять и удалять записи (рис. 13.12):

 Готовое приложение MultiFillingAndUpdating

увеличить изображение
Рис. 13.12. Готовое приложение MultiFillingAndUpdating

В программном обеспечении к курсу вы найдете приложение MultiFilling AndUpdating (Code\Glava6\MultiFillingAndUpdating).

При реализации обновления связанных таблиц программным образом следует передавать изменения в особом порядке3Этот фрагмент является переводом статьи "Database Updates from Datasets" из MSDN (заголовок раздела "Updating Related Tables").. Обычным сценарием является добавление родительских и относящихся к ним дочерних записей в набор данных, - например, запись о новом клиенте и одна или две относящиеся к ней записи о заказах. Если сам набор данных заставляет использовать правила реляционной целостности, возникнут ошибки при отсылке дочерних записей в базу данных до создания родительских записей.

И наоборот, при удалении связанных записей из набора данных обычно необходимо отправлять обновления в обратном порядке: сначала дочерние таблицы, а потом родительские таблицы. В противном случае в наборе данных может возникнуть ошибка, так как правила ссылочной целостности не дадут удалить родительскую запись, если существуют дочерние записи.

Существует следующие правила отсылки обновлений в таблицы:

  • Дочерняя таблица: удаление записей.
  • Родительская таблица: вставка, обновление и удаление записей.
  • Дочерняя таблица: вставка и обновление записей.