Главная » C# » Создание отношений между таблицами в Visual C# (Sharp)

0

Первым  шагом  в  использовании  Dataset  Designer  будет  преобразовать  таблицы в Database Explorer в формат, с которым Dataset Designer может работать. Для этого в Solution Explorer дважды щелкните по файлу с расширением xsd; в нашем прере это будет файл lotteryDataSet.xsd. Файл с расширением xsd — это файл XML Schema Definition (определение схемы XML), который преобразует наборы данных базы данных в файлы XML.

Файл lotteryDataSet.xsd имеет несколько дочерних файлов, которые можно открыть и просмотреть их содержание. Эти файлы являются частью коллекции, используой Dataset Designer. Но изо всех этих файлов модифицировать можно только файл lotteryDataSet.cs. Все прочие файлы управляются Dataset Designer.

Мы хотим создать отношения между тремя таблицами. Важность отношений состоит в том, что они позволяют нам поддерживать непротиворечивость базы данных. Как пример ситуации, которых мы хотим избежать, представьте добавление владельца выигравшего лотерейного билета в таблицу winners для розыгрыша, которого не было. С помощью отношений мы можем выполнять принудительную проверку на непротиворечивость, таким образом, требуя, чтобы в базе данных существовала запись для розыгрыша с определенной датой, прежде чем можно добавлять владелев выигравших билетов для этой даты. Определим два отношения: между таблици winners и draws и между таблицами winners и persons. Не забывайте, что табла winners содержит перекрестные ссылки между таблицами persons и draws.

Для определения отношений, выполните следующие операции:

1. Дважды щелкните файл lotteryDataSet.xsd в Solution Explorer. Будет выведено сообщение (рис. 14.10), дающее нам знать, что Dataset Designer не имеет данных для вывода.

2. Перетащите каждую из ранее созданных таблиц из Database Explorer в Dataset Designer (рис. 14.11). Это автоматически добавит стандартную поддержку для этих трех таблиц.

Рис. 14.10. Dataset Designer не имеет данных для вывода

Рис. 14.11. Помещение таблиц в Dataset Designer

Рис. 14.12. Создание отношения между таблицами winners и persons

3. Чтобы создать отношение, щелкните правой кнопкой мыши по поверхности гератора данных и в появившемся контекстном меню выберите последователость команд Add | Relation. Будет  выведено диалоговое окно Relation,  с пощью которого можно ассоциировать две таблицы посредством специального поля.

4. Укажите таблицу winners в качестве родительской таблицы,  а  таблицу persons — в качестве дочерней. Таблицы связываются по столбцу id. Нажмите кнопку ОК , чтобы создать отношение.

Отношение между таблицами winners и draws определяется так же, как и отношие между таблицами winners И persons, ТОЛЬКО связываются столбцы draw_date (рис. 14.13).

Рис. 14.13. Создание отношения между таблицами winners и draws

После создания отношений окно Dataset Designer должно выглядеть так, как покано на рис. 14.14.

На рис.  14.14 отображена четкая структура базы данных, включающая отношения. Структура играет важную роль для Dataset Designer, т. к. она определяет формат автоматически генерируемого кода. Посмотрите внимательно на рис. 14.14 и обрите внимание на надпись Fiil,GetData() внизу представления каждой таблицы. Методы  Fill о и GetData ()  применяются для  получения данных с  базы данных и преобразования их в данные, с которыми может работать язык С#.

Рис. 14.14. Dataset Designer после создания отношений между таблицами

Рис. 14.15. Свойства структуры таблицы в Dataset Designer

Есл и  щелкнут ь  мышь ю  п о  текст у  F i n  о   ил и  GetDatao ,  т о  Datase t  Designe r  выве – де т  панел ь  свойст в  (рис .   14.15).

В свойства х показа н точны й синтакси с дл я коман д SQ L INSERT И SELECT. Ка к мы помним , эт и дв а оператор а применяютс я  дл я  добавлени я  и  извлечени я  данны х  и з табли ц  ба з  данных .   Эт о   показывает ,  чт о  ко д  Datase t  Designe r  ниче м   н е  отличаетс я о т  код а  ADO.NET .

Тепер ь рассмотри м код , сгенерированны й Datase t Designe r дл я  привязк и  столбцо в таблиц ы  draws к  сгенерированно й  структур е  данных .

private void InitAdapter() {

this .^adapter – new global::System.Data.SqlServerCe.SqlCeDataAdapter(); global::System.Data.Common.DataTableMapping tableMapping =

new global: :System.Data.Common.DataTableMapping() ; tableMapping.SourceTable = "Table"; tableMapping.DataSetTable = "draws"; tableMapping.ColumnMappings. Add(,,draw_date", "draw_date") ;

tableMapping .ColumnMappings .Add (" first_number", " first_number") ;

tableMapping.ColumnMappings .Add{ "second_number", "second_number") ; tableMapping. ColumnMappings. Add (" third_number11, " th-ird_number") ;

tableMapping.ColumnMappings.Add("fourth_number",  "fourth_number"); tableMapping.ColumnMappings.Add("fifth_number",  "fifth_number"); tableMapping.ColumnMappings.Add("sixth_number",  "sixth_number"); tableMapping.ColumnMappings.Add("bonus",  "bonus"); this._adapter.TableMappings.Add(tableMapping); this.„adapter.InsertCommand =

new global:: System. Data. SqlServerCe. SqlCeCcomand () ; this._adapter.lnsertCanmand.Connection = this.Connection; thie._adapter.IneertCaninand.ComnandText =

"INSERT INTO [draws] ([draw_date], [first_nuiriber], [second_number], [third_nuiriber]" +

[fourth_nuiriber], [fifth_nuiriber], [sixth_number], [bonus]) VALUES (@pl, @p2, @p" +

"3, @p4, @p5, @p6, 0p7,

this.„adapter. InsertConinand.CoamtfmdType = global:: System. Data. CanmandType. Text;

global:: System. Data. SqlServerCe. SqlCeParameter par am = new global::System.Data.SqlServerCe.SqlCeParameter();

param. PararrveterNarrve = "@pi";

par am.DbType = global::System.Data.DbType.DateTime; param. IsNullable = true;

param.SourceColumn = "draw_date";

thi s. „adapter. InsertCcmnand. Parameters. Add (param) ;

param = new global::System.Data.SqlServerCe.SqlCeParameter(); param. ParameterName = "<ap2";

param. DbType = global::System. Data.DbType.Int32; param. IsNullable = true;

param.SourceColumn = "first_nuiriber";

thi s. „adapter. insertconmand. Parameters. Add (param) ;

param = new global::System.Data.SqlServerCe.SqlCeParameter() ; param.ParametezName = "@p3";

param. DbType = global::System.Data.DbType.Int32; param. IsNullable = true;

param.SourceColumn = "second_number";

Выделенный жирным шрифтом код показывает, насколько близким является сгерированный код к версии кода, используемого для добавления данных в разделе на ADO.NET. Сгенерированный код более ясный и подробный, чем предыдущий код, но это не имеет значения, т. к. разработчик не должен редактировать сгенерованный код, а пользоваться Dataset Designer.

ПРИМЕЧАНИЕ

Одно из преимуществ Dataset Designer состоит  в  том,  что  нам  не  нужно  предостаять связи между С# и базой данных. Кроме этого, Dataset Designer позволяет с леостью осуществлять связывание пользовательского  интерфейса  с  базой  данных. Dataset Designer генерирует такой код ADO, который бы был написан вручную разротчиком. Но, предоставляя графический интерфейс пользователя, Dataset Designer намного упрощает  задачу  написания  кода.

Использование сгенерированного кода

Использовани е кода , сгенерированног о Datase t Designer , н е  представляе т  никаки х пробле м пр и  условии ,  чт о  в ы  знаете ,  чт о  в  не м  происходит .  Datase t  Designe r  гене – рируе т  дв а  главны х  фрагмент а  кода :  адапте р  табли ц  и  набо р  данных .  Адапте р  таб – ли ц  представляе т  собо й  код ,  используемы й  дл я   прямог о   взаимодействи я   с   табли – цей : дл я добавления , выборк и и удалени я записей . Пр и выборк е данных ,  данны е заполняю т   набо р  данных .

Дале е    приводитс я    ко д   дл я    вставлени я    запис и    в    таблиц у    draws (ко д    находитс я

В приложени и   DatabaseConsoleEx): DatabaseConsoleEx.lotteryDataSetTableAdapters.drawsTableAdapter table =

new  DatabaseConsoleEx.lotteryDataSetTableAdapters.drawsTableAdapter();

table.Insert(DateTime.Now, 2, 2, 2, 2, 2, 2, 2);

Ко д н е представляе т собо й ничег о сложного . В не м создаетс я экземпля р drawsTableAdapter, посл е  чег о  вызываетс я   мето д   insert о ,   чтоб ы   добавит ь   за – пись .  Подключени е  к  баз е  данных ,   исполнени е   команд ы   и   присваивани е   парамет – ро в   выполняетс я   автоматически .

ПРИМЕЧАНИЕ

Автоматически генерируемый код является и добром, и злом одновременно. Добром потому, что  он  скрывает сложности  и  облегчает  вашу  работу.  Но,  как было  показано во фрагментах кода, довольно много работы выполняется за кулисами, и если вы не понимаете ADO.NET, то не будете знать, что делать, когда что-то пойдет не так. Например, когда выполняется подключение к базе данных? Единственным способом узнать это будет разобраться с автоматически сгенерированным кодом и проследить вызовы ADO.NET. Поступив  таким образом,  мы  узнаем,  что  подключение  к  базе данных  происходит  при  первом  вызове  метода  SQL  (например,   метода   inser t О) , а не при  инициализации  адаптера.

Дл я   извлечени я  в  цикл е  записе й   и з  таблиц ы  можн о  использоват ь  следующи й  код :

DatabaseConsoleEx.lotteryDataSet dataset = new DatabaseConsoleEx.lotteryDataSet();

DatabaseConsoleEx.lotteryDataSetTableAdapters.drawsTableAdapter table = new  DatabaseConsoleEx.lotteryDataSetTableAdapters.drawsTableAdapter();

int count = table.Fill(dataset.draws);

Console.WriteLine("Record count is (" + dataset.draws.Count + ")(" + count + ") ") ;

foreach (DatabaseConsoleEx.lotteryDataSet.drawsRow row in dataset.draws) {

Console.WriteLine("Date (" + row.draw_date + ") (" +

row. first_number + ")") ;

}

Переменная  table инициализируется  адаптером,  который  подключается  к  таблице

draws. Переменная dataset является пустой коллекцией для таблицы draws.

Для заполнения коллекции  вызывается  метод  table.Fill(),  а  назначением  являея член данных  dataset. draws. После вызова метода Fill о считывается количтво записей  и  присваивается переменной  count.

Для обработки в цикле отдельных строчек таблицы применяется оператор цикла foreach. Он обращается к типу  drawsRow и каждый экземпляр данного типа  имеет член данных, который представляет столбцы draw_date, f irst_number и др. Обротка в  цикле отдельных строчек таблицы  похожа  на обработку  в  цикле  коллекции. В примере ADO.NET использовался цикл while и требовалось знать, какой столбец ассоциируется с  каким  полем  SELECT.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии