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

Типизированный объект DataSet. Чтение и запись XML-документов

Создание типизированного объекта DataSet

Разобравшись наконец со всеми понятиями, приступим к их применению. Как мы знаем, объект DataSet представляет собой кэш, буфер для хранения данных, получаемых из базы. Он состоит из объектов DataTable (таблиц), DataColumn (столбцов) и DataRow (записей). Все столбцы в самой базе данных, разумеется, типизированы - то есть для каждого из них определен тип данных, например, int для ключевого поля, string для примечаний, date/time для даты или времени. При программном создании основных объектов ADO .NET для вывода столбцов из базы данных в объект DataSet, а затем в элемент DataGrid, информация о типах данных, не говоря уже об отношениях между таблицами, теряется. Конечно, можно программно же детализировать структуру объекта DataSet - создать таблицы, поля, определить тип данных полей, создать отношения (именно этим мы и занимались в "Объекты DataTable, DataRow и DataColumn" ), но, наверное, это не самый быстрый и удобный способ определения структуры DataSet. Разумеется, всякая структура лучше простого вывода данных, однако технология ADO .NET предлагает универсальный способ создания типизированных объектов - использование XSD-схем.

С типизированными объектами DataSet мы имели дело с самого начала курса - просто мы не обращали на это внимание. Откройте проект VisualDataMDB из "Элементы работы с базами данных" , в окне Solution Explorer щелкаем дважды на файле dsCustomer.xsd - появляется элемент со всеми полями таблицы Customer (рис. 11.10):

 XSD-схема dsCustomer.xsd в проекте VisualDataMDB

Рис. 11.10. XSD-схема dsCustomer.xsd в проекте VisualDataMDB

Вся структура таблицы, включая тип данных и ключевое поле (поле Customer ID, отмечено значком ключа), воспроизведена в этом файле. При запуске приложения среда формирует объект DataSet на основании XSD-схемы.

Приступим теперь к созданию типизированного DataSet. В качестве исходной базы данных воспользуемся файлом BDTur_firm.mdb из "Элементы работы с базами данных" . Скопируйте его, переименуйте в BDTur_firm_Eng.mdb и откройте в Microsoft Access. Изменим названия таблиц "Туры", "Сезоны", "Путевки", "Оплата" и поля в них так, как это было сделано в таблице 11.6 (см. также рис. 11.8). В результате у нас получится следующая схема данных (рис. 11.11).

 Схема данных в файле BDTur_firm_Eng.mdb

увеличить изображение
Рис. 11.11. Схема данных в файле BDTur_firm_Eng.mdb

Создайте новое Windows-приложение и назовите его "TypedDataSet". Перетаскиваем на форму элемент управления DataGrid, его свойству Dock устанавливаем значение Fill. Переходим в код формы, подключаем пространство имен:

using System.Data.OleDb;

В классе формы создаем строки commandText и commandText2 для извлечения содержимого таблиц TOUR и SEASON, а также строку подключения connectionString:

string commandText = "SELECT * FROM TOUR";
string commandText2 = "SELECT* FROM SEASON";
string connectionString = @"Provider=""Microsoft.Jet.OLEDB.4.0"
 ";Data Source=""D:\Uchebnik\Code\Glava5\BDTur_firm_Eng.mdb"
 ";User ID=Admin;Jet OLEDB:Encrypt Database=False";

Обратите внимание на адрес каталога базы BDTur_firm_Eng.mdb - приведенное значение верно только лишь для моего компьютера! В конструкторе формы создаем объекты для вывода содержимого двух таблиц в элемент DataGrid:

public Form1()
		{
			InitializeComponent();
			OleDbConnection conn = new OleDbConnection(connectionString);
			OleDbCommand myCommand = new OleDbCommand();
			myCommand.Connection = conn;
			myCommand.CommandText = commandText;
			OleDbDataAdapter dataAdapter = new OleDbDataAdapter();
			dataAdapter.SelectCommand = myCommand;
			DataSet ds = new DataSet();
			
			dataAdapter.TableMappings.Add("Table", "TOUR");
					
			OleDbCommand myCommand2 = new OleDbCommand();
			myCommand2.Connection = conn;
			myCommand2.CommandText = commandText2;
			OleDbDataAdapter dataAdapter2 = new OleDbDataAdapter();
			dataAdapter2.SelectCommand = myCommand2;
			dataAdapter2.TableMappings.Add("Table", "SEASON");

			conn.Open();
			dataAdapter.Fill(ds);
			dataAdapter2.Fill(ds);
			conn.Close();
			dataGrid1.DataSource = ds;
	
		}

Практически этот же код мы использовали в проекте DataGrid2Table в "Объекты DataTable, DataRow и DataColumn" . Запускаем приложение. Обратите внимание, что таблице не связаны - в самом деле, мы ведь не создавали никаких отношений (рис. 11.12).

 Приложение TypedDataSet. Вывод двух таблиц  TOUR и SEASON. Объект DataSet обычный, нетипизированный, создан программно

увеличить изображение
Рис. 11.12. Приложение TypedDataSet. Вывод двух таблиц TOUR и SEASON. Объект DataSet обычный, нетипизированный, создан программно

В окне Solution Explorer щелкнем правой кнопкой на названии проекта "TypedDataSet" и в появившемся контекстном меню выберем пункт "Add \ Add New Item". В окне шаблонов выделяем объект DataSet, называем его "XSDTour_bd.xsd" и нажимаем кнопку "Open" (рис. 11.13).

 Добавление схемы XSDTour_bd.xsd

Рис. 11.13. Добавление схемы XSDTour_bd.xsd

В результате мы добавили к проекту не только XSD-схему, но еще и дополнительный файл, который будет необходим для создания объекта DataSet на основе этой схемы. В окне доступен также шаблон XML Schema - именно его мы и использовали для создания схемы к документам XML, он тоже имеет расширение .xsd. Что будет, если мы выберем его? После добавления к проекту в окне Solution Explorer щелкните на кнопку - Show All Files ("Показывать все файлы"). В результате будут отображены все файлы в проекте, в том числе и те, которые обычно скрыты. При выборе объекта XML Schema среда генерирует два файла - XSDTour_bd.xsd и XSDTour_bd.xsx (рис. 11.14, А). В файл XSDTour_bd.xsx записываются данные о расположении элементов в режиме дизайна XSD-схемы - в этом можно убедиться, открыв его:

<?xml version="1.0" encoding="utf-8"?>
<!--This file is auto-generated by the XML Schema Designer.
 It holds layout information for components on the designer surface.-->
<!-- Этот файл сгенерирован автоматически в режиме дизайна XML-схемы.
 Он хранит информацию о расположении компонент --> 
<XSDDesignerLayout />

При выборе объекта DataSet добавляется также файл XSDTour_bd.cs (рис. 11.14, Б):

 Добавление XSD-схемы. А - объект XML - Schema, Б - DataSet

увеличить изображение
Рис. 11.14. Добавление XSD-схемы. А - объект XML - Schema, Б - DataSet

Как мы знаем, в файлах с расширением *.cs хранится код на языке C#. Это и есть тот файл, в котором будет храниться описание структуры DataSet. В принципе, можно работать и с объектом XSD-Schema в чистом виде, но тогда нам придется создавать самим файл XSDTour_bd.cs. Можете просмотреть его содержимое, сгенерированное автоматически, и убедиться в том, что среда в этом случае действительно облегчает работу.

Итак, "правильный" файл XSDTour_bd.xsd создан. Переходим в окно Server Explorer и создаем подключение к базе данных Microsoft Access BDTur_firm_Eng.mdb. Затем перетаскиваем таблицы TOUR и SEASON на поверхность схемы (рис. 11.15):

 Перетаскивание таблиц. Перевод надписи: "Для начала работы перетащите объекты из окна Server Explorer или Toolbox или щелкните правой кнопкой здесь"

Рис. 11.15. Перетаскивание таблиц. Перевод надписи: "Для начала работы перетащите объекты из окна Server Explorer или Toolbox или щелкните правой кнопкой здесь"

В результате у нас появились два элемента TOUR и SEASON, представляющих структуру соответствующих таблиц. Для создания отношения между таблицами переходим в окно Toolbox и перетаскиваем на элемент TOUR объект Relation (рис. 11.16):

 Перетаскивание объекта Relation

Рис. 11.16. Перетаскивание объекта Relation

В появившемся окне Edit Relation из выпадающего списка "Parent element" выбираем "TOUR", из выпадающего списка "Child element" выбираем "SEASON" - редактор сам определит верное ключевое поле IDTOUR, и нажимаем "ОК" (рис. 11.17, А). В режиме дизайна2Режимом дизайна здесь и далее будем называть графический вид элементов. схемы появляется схематическое изображение связи в виде ромба (рис. 11.17, Б):

 Создание отношения между таблицами. А - редактор Edit Relation, Б - схематическое изображение связи в режиме дизайна схемы

увеличить изображение
Рис. 11.17. Создание отношения между таблицами. А - редактор Edit Relation, Б - схематическое изображение связи в режиме дизайна схемы

Создание XSD-схемы завершено. Переходим на вкладку Data окна Toolbox и перетаскиваем на форму элемент DataSet. В окне Add DataSet оставляем предложенный вариант "Typed dataset" (рис. 11.18).

 Добавление объекта DataSet

Рис. 11.18. Добавление объекта DataSet

На панели компонент формы появляется объект xsdTour_bd1. Переходим в окно Properties и в свойстве Name вводим "dsTour". Здесь мы видим разницу3В "Объекты DataTable, DataRow и DataColumn" была фраза: "Свойство DataSetName используется для работы с XSD-схемами, но пока про это название (до Главы 5) мы можем просто забыть." Теперь про это свойство пора вспомнить. между свойством Name - названием, используемым в коде, и свойством DataSetName - названием объекта DataSet, которое образовано от схемы XSDTour_bd.xsd (рис. 11.19).

 Окно Properties объекта DataSet

Рис. 11.19. Окно Properties объекта DataSet

Переходим в код формы. Закомментируем создание экземпляра ds и заменим его на типизированный dsTour:

...
//DataSet ds = new DataSet();
...
//dataAdapter.Fill(ds);
//dataAdapter2.Fill(ds);
dataAdapter.Fill(dsTour);
dataAdapter2.Fill(dsTour);
conn.Close();
//dataGrid1.DataSource = ds;
dataGrid1.DataSource = dsTour;
...

Запускаем приложение. От записи в таблице TOUR можно перейти к дочерней таблице SEASON по отношению TOURSEASON (рис. 11.20):

 Приложение TypedDataSet. Вывод двух таблиц TOUR и SEASON. Типизированный объект DataSet (ср. рис. 11.12)

увеличить изображение
Рис. 11.20. Приложение TypedDataSet. Вывод двух таблиц TOUR и SEASON. Типизированный объект DataSet (ср. рис. 11.12)

Мы уже получали эту же функциональность в проекте DataGrid2Table, однако на этот раз мы обошлись без определения каких-либо отношений в коде. Название связи, выводимое в элемент DataGrid, - "TOURSEASON" трудно назвать удачным: его сгенерировала студия, для пользователей следует сделать его более понятным. Чтобы его изменить, следует перейти к схеме XSDTour_bd.xsd (в режим дизайна), щелкнуть правой кнопкой на символе связи - ромбике - и выбрать пункт "Edit Relation". Появится уже знакомый редактор (cм. рис.11.17, А), в котором можно будет изменить название. Впрочем, для нашего учебного проекта оставим его как есть.

Добавим в схему DataSet таблицы PASS и PAYMENT. Для этого снова откроем окно Server Explorer и перетащим их на схему XSDTour_bd.xsd. Из окна Toolbox добавим объект Relation на элемент SEASON - создадим связь с элементом PASS по полю IDSEASON. Аналогично, добавим объект Relation на элемент PASS для создания связи с элементом PAYMENT по полю IDPASS. Готовая схема будет иметь следующий вид (рис. 11.21):

 Готовая схема XSDTour_bd.xsd

увеличить изображение
Рис. 11.21. Готовая схема XSDTour_bd.xsd

Перейдем в режим кода формы, закомментируем строку command Text2 и объекты, нужные для извлечения таблицы SEASON:

...
//string commandText2 = "SELECT* FROM SEASON";
...
//OleDbCommand myCommand2 = new OleDbCommand();
//myCommand2.Connection = conn;
//myCommand2.CommandText = commandText2;
//OleDbDataAdapter dataAdapter2 = new OleDbDataAdapter();
//dataAdapter2.SelectCommand = myCommand2;
//dataAdapter2.TableMappings.Add("Table", "SEASON");
...
//dataAdapter2.Fill(dsTour);

Запускаем приложение: это кажется невероятным - мы оставили извлечение из базы данных только одной таблицы, а на форме отображается четыре связанных таблицы (рис. 11.22)!!

 Приложение TypedDataSet. Вывод схемы четырех таблиц

увеличить изображение
Рис. 11.22. Приложение TypedDataSet. Вывод схемы четырех таблиц

В действительности ничего удивительного нет - DataSet содержит структуру четырех таблиц, которую элемент DataGrid и отобразил на форме. Подключение к базе извлекает данные только для одной таблицы - TOUR, поэтому мы видим ее заполненной. Остальные таблицы - пустые, записей в них нет.

Мы очень быстро и легко воссоздали структуру фрагмента базы данных. Создание объектов DataTable, DataColumn, определение отношений - программно или с помощью визуальных средств студии - заняло бы гораздо больше времени.

Заполним DataSet данными из четырех таблиц. Добавим дополнительные строки commandText для извлечения содержимого остальных таблиц, в результате получится следующее:

string commandText = "SELECT * FROM TOUR";
string commandText2 = "SELECT* FROM SEASON";
string commandText3 = "SELECT* FROM PASS";
string commandText4 = "SELECT* FROM PAYMENT";

Также создадим дополнительные4Конечно, извлечь все эти таблицы можно и с помощью всего одного объекта DataAdapter. В шестой Главе мы научимся делать это объекты DataAdapter, конструктор формы примет следующий вид:

public Form1()
		{
			InitializeComponent();
			OleDbConnection conn = new OleDbConnection(connectionString);
			OleDbCommand myCommand = new OleDbCommand();
			myCommand.Connection = conn;
			myCommand.CommandText = commandText;
			OleDbDataAdapter dataAdapter = new OleDbDataAdapter();
			dataAdapter.SelectCommand = myCommand;
					
			dataAdapter.TableMappings.Add("Table", "TOUR");
					
			OleDbCommand myCommand2 = new OleDbCommand();
			myCommand2.Connection = conn;
			myCommand2.CommandText = commandText2;
			OleDbDataAdapter dataAdapter2 = new OleDbDataAdapter();
			dataAdapter2.SelectCommand = myCommand2;
			dataAdapter2.TableMappings.Add("Table", "SEASON");

			OleDbCommand myCommand3 = new OleDbCommand();
			myCommand3.Connection = conn;
			myCommand3.CommandText = commandText3;
			OleDbDataAdapter dataAdapter3 = new OleDbDataAdapter();
			dataAdapter3.SelectCommand = myCommand3;
			dataAdapter3.TableMappings.Add("Table", "PASS");

			OleDbCommand myCommand4 = new OleDbCommand();
			myCommand4.Connection = conn;
			myCommand4.CommandText = commandText4;
			OleDbDataAdapter dataAdapter4 = new OleDbDataAdapter();
			dataAdapter4.SelectCommand = myCommand4;
			dataAdapter4.TableMappings.Add("Table", "PAYMENT");

			conn.Open();
			dataAdapter.Fill(dsTour);
			dataAdapter2.Fill(dsTour);
			dataAdapter3.Fill(dsTour);
			dataAdapter4.Fill(dsTour);
			conn.Close();
			dataGrid1.DataSource = dsTour;
		}

Запускаем приложение. Все таблицы теперь заполнены данными (рис. 11.23).

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

Рис. 11.23. Готовое приложение TypedDataSet

В программном обеспечении к курсу вы найдете файл базы данных BDTur_firm_Eng.mdb и приложение TypedDataSet (Code\Glava5\ BDTur_firm_Eng.mdb и TypedDataSet).