Объекты DataTable, DataRow и DataColumn
Объекты DataTable, DataRow и DataColumn
Понятие DataSet, DataTable и DataColumn
Итак, DataSet представляет собой буфер для хранения данных из базы. Этот буфер предназначен для хранения структурированной информации, представленной в виде таблиц, поэтому первым, самым очевидным вложенным объектом DataSet является DataTable. Внутри одного объекта DataSet может храниться несколько загруженных таблиц из базы данных, помещенных в соответствующие объекты DataTable. Всякая таблица состоит из столбцов (называемых также полями или колонками) и строк. Для обращения к ним и для управления столбцами и строками в объекте DataTable предназначены специальные объекты - DataColumn и DataRow. Между таблицами, как мы знаем, могут быть связи - здесь они представлены объектом DataRelation. Наконец, в таблицах есть первичные и вторичные ключи - объект Constraint со своими двумя подклассами UniqueConstraint и ForeighKeyConstraint описывают их. Я все вр емя говорю "представлены", "описывают", избегая слов "отображают" и "определяются" - дело в том, что нельзя ставить знак равенства между, например, объектом DataRelation и связью таблиц. В загруженных таблицах не формируются автоматически все нужные объекты - кое-где мы должны делать это самостоятельно. Сами объекты имеют также довольно тонкую и сложную структуру, поэтому это было бы довольно грубым приближением. Однако, на первых порах, для понимания сути полезно держать в голове следующие "формулы":
DataSet = одна или несколько таблиц = один или несколько объектов DataTable. DataTable = таблица. DataColumn = столбец, поле, колонка. DataRow = строка. DataTable = таблица = несколько полей, столбцов, колонок = несколько объектов DataColumn. DataTable = таблица = несколько строк = несколько объектов DataRow. DataRelation = связь между таблицами.
Возникает вопрос: для чего нужны эти объекты, если мы прекрасно обходились и без них для вывода содержимого таблицы, например в элемент DataGrid? Дело в том, что для простого отображения информации создавать эти объекты не требуется, но тогда все данные будут однородными текстовыми переменными, подобно таблицам в документе Microsoft Word. DataSet не может сам сформировать структуру данных - тип переменных, первичные и вторичные ключи, связи между таблицами. Для управления структурой, для сложного отображения (например, вывод информации с привязкой к элементам, создаваемым в режиме работы приложения) и нужно определение этих объектов.
Лучший способ разобраться с работой всех объектов - применить их на практике. Создадим простую тестовую программу, в которой можно отвечать на вопросы, перемещаться по ним и определять количество верных ответов. Для хранения вопросов и вариантов ответов создадим базу данных Tests Microsoft SQL. База будет состоять всего из двух таблиц (рис. 8.1):
Каждый вопрос будет содержать несколько ответов, для синхронного перемещения по структуре нужна связь по полю questID. Галочка "Allow Nulls" (Разрешить пустые значения) снята для всех полей - это означает, что все поля будут обязательными для заполнения. Структура таблиц Questions и Variants приводится в таблице 8.1:
Таблица Поле | Описание поля |
---|---|
Questions - таблица вопросов | questID Номер вопроса |
question Текст вопроса | |
questType Тип вопроса (с одним правильным вариантом ответа или с несколькими) | |
Variants - таблица вариантов ответов | id Номер ответа |
questID Номер вопроса | |
variant Текст варианта ответа | |
isRight Является ли данный ответ верным |
Для нас не столь важно количество вопросов, поэтому их всего будет пять, относящихся к теме операционной системы Windows XP. Одному вопросу может соответствовать один правильный вариант ответа - в этом случае в поле questType указывается значение "0". Далее на форме эти варианты будут выводиться с элементами RadioButton. Для вопросов, у которых есть несколько правильных вариантов ответов, указывается в поле questType значение "1". На форме такие варианты будут выводиться с чекбоксами. В таблицах 8.2 и 8.3 приводится содержимое таблиц Questions и Variants.
id | questID | Variant | isRight |
---|---|---|---|
1 | 1 | C:\Program Files\Outlook Express\Mail | 0 |
2 | 1 | C:\Documents and Settings\Имя_Пользователя\ Local Settings\Application Data\Identities\ {F4CB90C4-3FD5-406B-83FB-85E644627B87}\Microsoft\Outlook Express | 1 |
3 | 1 | C:\WINDOWS\system32\Microsoft\Outlook Express\Bases | 0 |
4 | 1 | C:\Documents and Settings\Default User\Cookies | 0 |
5 | 2 | "Мой компьютер - правая кнопка - Свойства - Вкладка "Общие" на подписи - правая кнопка - Свойства - Переименовать" | 0 |
6 | 2 | [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion] затем меняем параметры RegisteredOwner и RegisteredOrganization | 1 |
7 | 2 | [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT] удаляем раздел CurrentVersion | 0 |
8 | 2 | [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run] | 0 |
9 | 3 | *.mpeg, *.mdb, *. Htm | 0 |
10 | 3 | *.xls, *.txt , *.mht | 1 |
11 | 3 | *. jpeg, *.gif, *.mp3 | 0 |
12 | 3 | *. doc, *. xml, *.bmp | 1 |
13 | 4 | update, insert, sum | 0 |
14 | 4 | where, like, create | 0 |
15 | 4 | count, min, max | 1 |
16 | 4 | select, avg, into | 0 |
17 | 5 | Отключилась проверка на ошибки всех дисковых разделов при загрузке Windows ХР | 1 |
18 | 5 | Установлен таймер на автоматическое отключение | 0 |
19 | 5 | Отключены все диагностические сообщения | 0 |
20 | 5 | Система перестанет загружаться | 0 |
В поле isRight таблицы Variants правильные ответы отмечаются значением "1". Понятно, что для практического применения тестовой программы следует ограничить доступ к базе данных Tests. Мы, однако, будем использовать подключения без пароля.
Создайте новое Windows-приложение и назовите его "Tests". Устанавливаем следующие свойства формы:
Form1, форма, свойство | Значение |
---|---|
FormBorderStyle | FixedSingle |
MaximizeBox | False |
Size | 550; 350 |
Text | Тест |
Перетаскиваем на форму TextBox, GroupBox, Label и пять кнопок, устанавливаем следующие значения свойств элементов:
textBox1, свойство | Значение |
---|---|
Name | txtQuestion |
Location | 12; 24 |
Multiline | True |
Size | 520; 90 |
TabIndex | 8 |
Text |
Интерфейс приложения готов. Чекбоксы или элементы radioButton мы будем добавлять в режиме запуска приложения - в самом деле, длина всех ответов разная и делать привязку к статичным элементам нет смысла. Переключаемся на вкладку Data панели инструментов Toolbox и перетаскиваем на форму объект DataSet. В появившемся окне Add DataSet выбираем значение "Untyped DataSet" и нажимаем "OK". Появляется панель компонентов, с которой мы уже неоднократно имели дело. Свойству Name устанавливаем значение dsTests.
В свойстве Tables элемента DataSet нажимаем на кнопку(...), запускается редактор Table Collection Editor (рис. 8.2), нажимаем кнопку "Add" и вводим следующие значения свойств:
Значение dtQuestions свойства Name указывает название созданного объекта DataTable, а значение Questions свойства TableName указывает название таблицы, которая будет помещена в DataTable. Добавим поля к объекту DataTable. В редакторе Tables Collection Editor в поле свойства Columns нажимаем на кнопку(...), появляется редактор Columns Collection Editor (рис. 8.3), нажимаем кнопку Add. Всего нужно будет создать три поля: questID, question и questType:
Завершив работу с редактором Columns Collection Editor, нажимаем кнопку Close. Мы закончили создание объекта DataTable для таблицы Questions. Аналогичные действия надо проделать, чтобы создать DataTable для таблицы Variants (рис. 8.4) и соответствующих полей id, questID, variant и isRight:
В базе данных Tests таблицы Questions и Variants мы связали по полю questID. Теперь при проектировании схемы базы нам следует также создать это отношение. В окне Properties объекта DataSet нажимаем на кнопку (_) в поле свойства Relations. В появившемся редакторе Relations Collection Editor нажимаем кнопку "Add" для добавления связи. Называем отношение "QuestionsVariants", а в качестве ключевого поля указываем questID (рис. 8.5):
Мы закончили работу с визуальными средствами. Программное создание объектов DataTable, DataColumn, DataRelation (см. далее) обеспечивает, при прочих равных условиях, большую производительность, однако редакторы позволяют быстрее осуществлять редактирование и обладают большей наглядностью. На первых порах проще работать именно с ними, но по мере роста опыта следует отказаться от их применения.