Вы находитесь на странице: 1из 538

Анатолий Постолит

Visual

Studio.NET:

Разработка приложений баз данных

Санкт-Петербург

«БХВ-Петербург»

2003

УДК

6S1.3.06

ББК

32.973.26

П63

П63

Постолит А. В. Visual Studio .NET: разработка приложений баз данных. — СПб.: БХВ-Петербург, 2003. — 544 с.: ил.

ISBN 5-94157-309-Х Книга посвящена технологии Microsoft .NET и базовому инструментальному средству этой технологии Visual Studio .NET. Разъясняется сущность новой модели доступа к данным ADO.NET, упрощающей создание как традиционных Windows- приложений, так и распределенных систем, работающих в сети Интернет, Пред- ставлены материалы, необходимые для практического программирования, пройде- ны все этапы создания приложений от формирования пустой формы до установки конечного продукта у клиента. Рассмотрены особенности базовых объектов досту- па к данным и элементов управления. Основное внимание уделено взаимодейст- вию различных типов приложений с базами данных. Все ситуации разбираются на конкретных примерах, реализованных на двух языках программирования: Visual Basic и С#. Книга может быть использована как лабораторный практикум для сту- дентов вузов и слушателей компьютерных курсов при изучении практических приемов программирования в среде Visual Studio .NET.

Для

программистов

УДК 681.3.06

ББК 32.973.26

Группа подготовки издания:

Главный редактор Зам. главного редактора Зав. редакцией Редактор Компьютерная верстка Корректор Оформление серии Дизайн обложки Зав. производством

Екатерина Кондукова Анатолий Адаменко Григорий Добин Дмитрий Лещев Татьяна Валерьянова Евгений Камский Via Design Игоря Цырульникова Николай Тверских

Лицензии ИД № 02429 от 24.07.00. Подписано в печать 25.04.03. Формат 70х100 1 /16. Печать офсетная. Усл. печ. л. 43,86. Тираж 3000 экз. Заказ № 873 "БХВ-Петербург", 198005, Санкт-Петербург, Измайловский пр., 29.

Гигиеническое заключение на продукцию, товар I* 77.99.02.Э53.Д.001537.03.02 от 13.03.2002 г. выдано Департаментом ГСЭН Минздрава России.

Отпечатано с готовых диапозитивов в Академической типографии "Наука" РАН 19Э034, Санкт-Петербург, 9 линия, 12.

ISBN 5-94157-309-Х

О Постолит А. В. , 2003

О Оформление, издательство "БХВ-Петербург", 2003

Содержание

Об авторе 10 Введение 11 Глава 1. ADO.NET как базовый объект доступа к
Об авторе
10
Введение
11
Глава
1.
ADO.NET как базовый объект доступа к базам данных
14
1.1, Структура компонента доступа
к данным ADO.NET
14
Л. Работа в отрыве от источника данных
15
.2.
Взаимодействие с базой данных
Взаимодействие с базой данных
через команды
17
.3.
через объект DataSet
18
.4. Независимость набора данных DataSet
от источника данных
20
.5.
Обмен данными в формате XML
21
.6.
Схемы, определяющие структуру данных
22
1.2.
Сравнение ADO.NET и ADO
22
1.2.1.
22
1.2.2.
Представление данных в памяти
Навигация по данным и курсоры
23
1.2.3.
Минимизация открытых соединений
,
24
1.2.4.
Разделение данных между приложениями
24
1.3.
Соединение с источником данных
(объект Connection)
25
1.3.1. Строка соединения
25
1.3.2. Открытие и закрытие соединения
26
1.3.3. Пул соединений
26
1.3.4. Транзакции
27
1.3.5. Конфигурирование свойств Connection
27
1.3.6. Объект Connection и безопасность
.
27
1.3.7. Создание объекта Connection в режиме дизайнера с помощью
Server Explorer
28
1.3.8. Инструменты Visual Studio для создания объектов Connection
29
1.3.9. Создание объекта Connection в ADO.NET
29
1.4.
Адаптер данных (объект DataAdapter)
32
1.4.1. Адаптеры данных и связанные таблицы
33
1.4.2. Адаптеры данных и объекты Command
34
1.4.3. Чтение и обновление данных с использованием объекта DataAdapter.
36
1.4.4. Параметры команд объекта DataAdapter
37
1.4.5. Свойство TableMappings объекта DataAdapter
44

_4

Содержание

1.4.6. Создание объекта DataAdapter.

 

48

1.4.7. Конфигурирование параметров

объекта DataAdapter

 

58

1.4.8. Связывание колонок таблиц

источника данных и объекта DataSet

через адаптер данных

 

61

1.4.9.

Предварительный просмотр данных, полученных объектом DataAdapter

65

Глава 2.

Наборы данных DataSet

 

67

2.1.

Отсоединенный набор данных

 

67

2.1.1. Объект DataSet, схемы и XML

 

68

2.1.2. Типизированные и нетипизированные объекты DataSet

 

69

2.1.3. Чувствительность к регистру в DataSet

 

71

2.1.4. Заполнение наборов данных

 

72

2.1.5. Указатель текущей записи и перемещение

по набору данных

 

72

2.

.6. Связанные таблицы и объект DataRelation

 

73

2.

.7. Ограничени я в DataSet

 

74

2.

.8. Обновление DataSet и базы данных

 

75

2.

.9. Инструмент ы Visual Studio

для создания объектов DataSet.

 

75

2.1.10. Создание вычисляемых колонок

объекта DataSet

 

81

2.1.11. Добавление таблиц в сформированный объект DataSet

 

S3

2.1.12. Добавление существующего типизированного объекта DataSet

 

к форме или компоненту

 

84

2.1.13.

Добавление объектов DataSet без контроля типов данных к форме

или компоненту

87

2.1.14. Способы фильтрации

и сортировки данных в DataSet

 

96

2.1.15. Фильтрация и сортировки данных

в DataSet с помощью объекта DataView

100

2.1.16. Фильтрация и сортировка

таблиц данных в DataSet.

 

104

2.1.17. Доступ

к записям в объекте DataView

 

106

2.1.18. Работа с коллекцией DataView

через объект DataViewManager

 

110

2.1.19. Реляционные отношения в DataSet

 

11 1

2.2.

Обновление набора данных

в Visual Studio .NET

 

118

2.2.1. Введение в обновление набора данных 118

2.2.2. Поддержание информации об изменениях в записях таблиц набора данных 122

2.2.3. Проверка правильности данных

 

127

2.2.4. Модификация, вставка и удаление записей в наборе данных

128

2.2.5. События при обновлении данных

132

2.2.6. Приостановка действия ограничений при изменении данных

133

2.2.7. Слияние наборов данных

135

2.2.8. Завершение изменений в наборе данных

 

136

2.3.

Передача изменений набора данных

в источник данных

 

137

2.3.1. Обновление баз данных из наборов данных

 

137

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

 

I4i

2.3.3. Регенерация набора данных

 

144

Содержание

5

2.3.4. Контроль параллелизма

2.3.5. Обработка ошибок модернизации

145

145

148

148

149

150

источника данных

и стратегии доступа к данным

Глава 3. Прямой доступ к базе данных

3.1. Прямой доступ к базе данных

адаптером

данных

3.1.1. Общие сведения об объекте DataCommand

3.1.2. Работа объектов DataCommand

3.1.3. Использование DataCommand

3.1.4. Использование объекта DataCommand

3.1.5. Выполнение команд, которые возвращают наборы данных

3.1.6. Выполнение обновления или модификации базы данных

с использованием DataCommand

3.1.7. Задание команды Data Command, возвращающей одно значение

151

152

158

162

166

167

168

169

3.2. Стратегии доступа к данным

3.2.1. Работа с данным и через объект DataSet

3.2.2. Непосредственная работа с элементами базы данных

3.2.3. Рекомендации по организации доступа к данным из приложений

 

170

Глава 4. Построение Windows-приложений с доступом к данным

через ADO.NET

Глава 4. Построение Windows-приложений с доступом к данным через ADO.NET

173Глава 4. Построение Windows-приложений с доступом к данным через ADO.NET

173
173

4.1. Создание Windows-приложения

 

173

4.2. Windows-форма как основа интерфейса

 

176

4.3. Доступ к данным в Windows-формах

с использованием

 

элемента

управления DataGrid

177

4.3.1. Создание проекта и формы

 

178

4.3.2. Создание набора данных DataSet

 

179

4.3.3. Добавление элемента управления DataGrid

для отображения данных

1864.3.3. Добавление элемента управления DataGrid для отображения данных

186
186
186

4.3.4. Заполнение элемента управления

4.3.5. Обновление информации в базе данных 189

187

DataGrid данными

4.4.

Доступ к данным в Windows-формах

с использованием текстовых полей

191

4.4.1. Связывание элементов TextBox с набором данных

 

193

4.4.2. Отображение номера текущей записи

 

196

4.5.

Выборка и сортировка данных

через запросы с параметрами

 

198

4.5.1. Создание проекта и Windows-формы

 

199

4.5.2. Создание и конфигурирование объектов

DataConnection и

DataAdapter

200

4.5.3. Создание набора данных

 

203

4.5.4. Добавление элементов отображения данных

 

204

4.5.5. Добавление кода для заполнения

набора данных

 

205

4.5.6. Связывание текстовых полей

с набором данных

 

207

4.5.7. Добавление навигации по записям

 

208

4.5.8. Отображение номера текущей записи

 

209

4.5.9. Тестирование работы приложения

 

211

б

Содержание

4.6.

Работа со связанными таблицами

в Windows-формах

 

213

4.6.1. Создание проекта и Windows-формы

 

214

4.6.2. Конфигурирование Data Connection и DataAdapter

 

215

4.6.3. Создание набора данных DataSet

 

217

4.6.4. Создание реляционных связей между таблицами набора данных

 

218

4.6.5. Добавление элементов отображения данных

 

220

4.6.6. Заполнение набора данных

 

223

4.6.7. Тестирование приложения

 

224

4.7.

Представление связанных таблиц

в элементе управления DataGrid

 

225

4.7.1. Создание проекта и Windows-формы

 

226

4.7.2. Конфигурирование объектов

Data Connection и DataAdapter

 

226

4.7.3. Добавление элементов управления

 

228

4.7.4. Заполнение набора данных

и создание реляционных связей

 

229

4.7.5. Тестирование приложения

   

231

4.8.

Добавление, удаление и обновление записей в Windows-формах

 

234

4.8.1.

Создание проекта и формы

235

4.8.2.

Создание и конфигурирование элементов доступа к данным

 

235

4.8.3.

Формирование программного кода

 

237

Глава 5.

Построение ASP-приложений

с доступом к данным через ADO .NET

243

5.1.

Создание проекта и формы

 

243

5.1.1. Структура Web-формы

 

245

5.1.2. Добавление элементов управления и текста

 

246

5.1.3. Создание обработчика события

 

252

5.1.4. Построение Web-приложения

и запуск Web-формы

 

253

5.2.

Работа с данными в Web-формах

 

254

5.2.1. Создание проекта и формы

 

255

5.2.2. Создание и конфигурирование набора данных

 

255

5.2.3. Добавление объекта DataGrid для отображения данных

 

259

5.2.4. Заполнение набора данных

и отображение информации в DataGrid.

261

5.2.5. Тестирования приложения

 

262

5.3.

Работа с данными,

доступными только для чтения

 

262

5.3.1. Создание проекта и формы

 

263

5.3.2. Добавление компонент доступа к данным

 

264

5.3.3. Добавление элементов отображения данных

 

267

5.3.4. Добавление программного кода

для выборки и отображения данных

269

5.3.5.

Тестирование приложения

 

270

5.4.

Редактирование информации на уровне источника данных из Web-форм

271

5.4.1. Создание проекта и формы

 

272

5.4.2. Добавление компонент для доступа к данным

 

273

5.4.3. Добавление элементов управления

 

278

Содержание

7

5.4.4. Добавление программного кода

для отображения и обновления данных279

5.4.5. Тестирование приложения

 

285

5.5.

Создание Web-приложения с доступом к данным

 

через компонент пользователя

286

5.5.1. Создание Web-формы

286

5.5.2. Создание и конфигурирование элементов доступа к данным

 

288

5.5.3. Создание набора данных

 

290

,

5.5.4. Связывание объекта DataGrid с набором данных

 

291

5.5.5. Фильтрация данных в Web-форме

 

299

5.5.6. Создание объекта с бизнес-логикой

 

304

5.5.7. Использование объекта с бизнес-логикой

 

306

Глава 6.

Дополнительные возможности ASP-приложений

 

309

6.1.

Проверка корректности вводимых

данных на Web-формах

 

309

6.1.1. Создание базовой формы

 

310

6.1.2. Добавление элементов ввода данных

 

311

6.1.3. Добавление контролей для проверки правильности данных

 

312

6.1.4. Проверка заполнения обязательных полей

313

6.1.5. Проверка формата текста

 

314

6.1.6. Проверка соответствия паролей

 

315

6.1.7. Отображение ошибок при проверке правильности данных

 

316

6.1.8. Тестирование приложения

 

317

6.2.

Использование серверного элемента управления DataGrid

 

для просмотра и редактирования данных

 

319

6.2.1. Создание проекта и формы

 

320

6.2.2. Создание и конфигурирование набора данных

 

320

6.2.3. Добавление элемента управления DataGrid для отображения данных

324

6.2.4. Заполнение набора данных и отображение информации в DataGrid 325

6.2.5. Добавление возможности

редактирования данных

 

327

6.2.6. Предварительная проверка работы

созданных элементов

 

331

6.2.7. Редактирование DataSet

обновление базы

данных

 

332

6.2.8. Тестирование приложения

338

6.2.9. Усовершенствование

примера

 

339

6.2.10. Кэширование набора данных

 

342

6.3.

Создание постраничного доступа к данным с использованием DataGrid

6.3. Создание постраничного доступа к данным с использованием DataGrid
6.3. Создание постраничного доступа к данным с использованием DataGrid
Создание постраничного доступа к данным с использованием DataGrid 344

344

6.3.1. Создание проекта и формы

345

6.3.2. Добавление компонентов доступа к данным

 

346

6.3.3. Добавление элемента управления DataGrid

 

348

6.3.4. Добавление программного кода для выборки

и отображения данных

 

350

6.3.5. Тестирование приложения

357

6.4. Добавление, удаление и обновление записей в Web-формах

 

357

6.4.1.

Создание проекта и формы

 

358

8 Содержание 6.4.2. Создание и конфигурирование элементов доступа к
8
Содержание
6.4.2. Создание и конфигурирование элементов доступа к данным
359
6.4.3. Формирование программного кода
361
Глава 7.
Основные понятия о Web-сервисах
370
7.1. Структура и назначение Web-сервисов
370
7.2. Создание простейшего Web-сервиса
371
7.2.1. Создание проекта XML Web Service
371
7.2.2. Формирование программного кода Web-сервиса
372
7.2.3. Тестирование Web-сервиса
374
7.2.4. Отладка Web-сервиса
376
7.2.5. Развертывание Web-сервиса
377
7.3. Доступ к Web-сервису
из клиентского приложения
381
7.3.1. Создание приложения клиента Web-сервиса
381
7.3.2. Добавление ссылки на Web-сервис
383
7.3.3. Доступ к Web-сервису из приложения клиента
384
7.4. Использование общедоступных
Web-сервисов через сеть Интернет
385
Глава 8.
Доступ к базам данных
через Web-сервисы
388
8.1. Распределенные приложения
388
8.2. Этапы создания
распределенных приложений
390
8.3. Реализация бизнес-логики распределенных приложений
на основе Web-сервиса
391
8.3.1. проекта Web-сервиса
Создание
392
8.3.2. соединения с базой данных
Создание
и адаптера данных
393
8.3.3. Конфигурирование интегрированной идентификации
396
8.3.4. Создание определения класса
набора данных DataSet
398
8.3.5. Представление набора данных другим приложениям
:
399
8.4. Виды приложений- клиентов Web-сервисов
403
8.5. Доступ к Web-сервисам из Windows-приложений
403
8.5.1. Создание Windows-приложения
404
8.5.2. Добавление к форме элементов управления
406
8.5.3. Программный код загрузки и обновления данных
408
8.5.4. Тестирование приложения
411
8.6. Доступ к Web-сервисам
из Web-приложений
411
8.6.1. Создание проекта и Web-формы
412
8.6.2. Добавление к форме элементов управления
413
8.6.3. Программный код загрузки
и обновления данных
416
8.6.4. Тестирование приложения
421
Глава 9.
Развертывание приложений
423
9.1. Инсталляция Windows-приложений
423
9.1.1. Создание и установка приложения
423

Содержание

9

9.1.2. Создание ярлыка установленного приложения

на рабочем столе Windows

430

9.1.3. Модификация диалога с пользователем

 

433

9.1.4. Задание дополнительных свойств установщика проекта

 

439

9.1.5. Установка приложения MyWin на компьютере разработчика

 

440

9.2. Инсталляция Web-приложений

 

441

9.2.1. Создание проекта развертывания

 

442

9.2.2. Развертывание приложения на Web-сервере локального компьютера

444

9.2.3. Развертывание приложения на Web-сервере сети

 

446

9.2.4. Демонтаж Web-приложения

 

447

Глава 10.

Удаленная работа с базами данных через Интернет-сайты

449

10.1. Постановка задачи

449

10.2. Структура базы данных

 

452

10.3. Создание Web-сервиса

 

453

10.3.1. Функции регистрации и идентификации пользователей

455

10.3.2. Функции работы с каталогом товаров

465

10.3.3. Функции для работы с заказами клиентов

 

471

10.3.4. Функции работы с содержимым

заказов клиентов

 

484

10.4.

Разработка клиентской части приложения

 

495

10.4.1. Разработка Web-формы для регистрации и идентификации пользователей 496

10.4.2. Разработка Web-формы для получения доступа к каталогу товаров

10.4.3. Разработка Web-формы для получения доступа к заказам клиентов 513

10.4.4. Разработка Web-формы для добавления товаров в заказ клиента 524

10.4.5. Тестирование приложения

536

506

Послесловие

539

Список литературы

 

540

Об авторе

Постолит Анатолий Владимирович — доктор технических наук, профессор Московского автомобильно-дорожного института (технического универси- тета). Увлекся автомобилями, компьютерами и программированием еще бу- дучи студентом. Создавал программные средства практически для всех ти- пов компьютеров — от "Минск-32" и "Проминь" до современных ПЭВМ. Преподавал на кафедрах прикладной математики, вычислительной техники, эксплуатации автотранспорта и автосервиса. В настоящее время работает в крупной транспортной компании "Мострансавто" и занимается разработкой информационных систем для автотранспортного комплекса. Специализиру- ется на создании региональных информационных систем на основе MS SQL Server, VB6, с использованием, в последнее время, Visual Studio .NET. Ваши пожелания, вопросы и предложения присылайте автору по адресу postolit@gupmta.ru.

Введение

Сегодня в мире насчитываются миллионы людей, использующих языки программирования Visual Basic и С для разработки прикладных систем. Причем подавляющее количество приложений обеспечивают взаимодейст- вие пользователей с различными базами данных: бухгалтерские, торговые, складские, транспортные, банковские и прочие системы. Как правило, кор- поративные пользователи нуждаются в распределенных приложениях, по- скольку подразделения фирм и их клиенты могут быть рассредоточены на достаточно большой территории.

Традиционно для создания распределенных систем использовались динами- ческие ASP (Active Server Pages, активные страницы сервера). Однако из-за больших трудозатрат и необходимости привлечения специалистов высокой квалификации стоимость таких систем остается высокой. Учитывая это об- стоятельство, фирма Microsoft реализовала технологию .NET, которая обес- печивает значительное снижение трудозатрат на реализацию распределен- ных информационных систем. В .NET-технологии коренным образом изме- нилась модель доступа к данным, что привело в замешательство многих программистов, использовавших ADO (ActiveX Data Objects, объекты дан- ных ActiveX). Новые неизвестные объекты, исчезнувшие свойства и методы традиционных объектов и элементов управления приводят сначала к расте- рянности, а затем к неудовлетворенности новым инструментальным средст- вом и неприятию этой технологии.

Данная книга посвящена разрешению этой проблемы. Она призвана помочь программистам, привыкшим работать с ADO, понять сущность нового под- хода к обработке данных, испытать новые возможности Visual Studio .NET на элементарных примерах, и, в конечном итоге, с минимальными потеря- ми времени адаптироваться к одной из самых перспективных технологий — Microsoft .NET.

В книге рассмотрены практически все элементарные действия, которые вы- полняют программисты, работая над реализацией прикладных систем. Пройдены все этапы от создания шаблона приложения до установки конеч- ного продукта у клиента. Рассмотрены особенности базовых объектов и элементов управления. Книга предназначена для программистов, знакомых с языками программирования Visual Basic и С, работавших с ADO, имею-

12

Введение

щих опыт взаимодействия с базами данных на основе языка SQL. В данном издании в малой степени освещены вопросы разработки интерфейса, а больше внимания уделено взаимодействию различных типов приложений (Windows-формы, Web-формы, Web-сервисы) с базами данных.

Первые три главы книги посвящены обзору ADO.NET — основному ком- поненту, обеспечивающему взаимодействие приложений с базами данных. Приводится структура этого компонента и его сравнение со знакомым большинству программистов компонентом доступа к данным — ADO. Подробно рассматриваются свойства и методы таких объектов как соеди- нение с базами данных, адаптеров данных и наборов данных, особенности работы приложений в отсоединенном от базы данных состоянии. Рассмат- риваются вопросы возможности выполнения операций манипулирования данными непосредственно на уровне базы данных с удаленных компьюте- ров (в рамках локальной сети или через Интернет), а также различные стратегии взаимодействия с данными при построении тех или иных типов приложений.

В четвертой главе обсуждается построение традиционных Windows- приложений с доступом к данным через ADO.NET. Рассматриваются во- просы редактирования данных через элемент управления DataGrid и тек- стовые поля, выборка данных через запросы с параметрами, работа со свя- занными таблицами, добавление, удаление и редактирование записей.

Пятая и шестая глава раскрывают тему построения ASP приложений с дос- тупом к данным через ADO.NET. Рассматривается процесс построения про- стейшей Web-формы, работа с данными удаленных пользователей через сеть Интернет, быстрая выборка информации из баз данных, доступных только для чтения, а также возможность редактирования информации непосредст- венно на уровне базы данных с удаленных компьютеров, не передавая их на рабочую станцию пользователя. Приводится пример взаимодействия при- ложения с базами данных через компонент пользователя, проверка кор- ректности вводимой информации на стороне удаленного клиента. Разбира- ются вопросы модификации данных с помощью серверного элемента управления DataGrid (добавление, удаление и обновление записей).

В седьмой главе приводятся основные понятия о Web-сервисах, их назначе- ние, создание, отладка и развертывание, а также показана технология дос- тупа к методам Web-сервисов из приложений-клиентов.

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

Введение

13

В девятой главе рассмотрены проблемы развертывания Windows-при- ложений на компьютерах конечных пользователей и Web-приложений на IIS (Web-серверах), описана последовательность создания инсталляционных пакетов. Заключительная десятая глава посвящена созданию Интернет-сайтов, обес- печивающих взаимодействие его посетителей с базами данных (с использо- ванием Web-сервисов). Описан полный цикл реализации распределенного приложения на примере торговой компании: постановка задачи, реализация модулей регистрации и идентификации пользователей, получение информа- ции из каталога продаваемых товаров, формирование заказов, их просмотр и редактирование. На протяжении всей книги раскрываемые вопросы сопровождаются доста- точно упрощенными, но полностью законченными примерами. Ход реше- ния той или иной задачи сопровождается большим количеством иллюстра- тивного материала. Желательно изучение тех или иных разделов выполнять непосредственно сидя за компьютером — тогда вы сможете последовательно повторять выполнение тех шагов, которые описаны в примерах, и тут же видеть результаты своих действий. Это в значительной степени облегчает восприятие приведенных в книге материалов. Наилучший способ обуче- ния — это практика. Все листинги программ приведены на двух языках:

Visual Basic и С#. Это прекрасная возможность познакомится еще с одним языком программирования или хотя бы понять, насколько эти два языка стали близки друг к другу. Оба языка используют одни и те же объекты, ме- тоды и свойства этих объектов. Основные отличия выражаются некоторыми особенностями синтаксиса. Фактически из разных языков программирова- ния идет обращение к одной и той же библиотеке классов .NET Framework Class Library. Итак, если вас заинтересовали вопросы создания прикладных систем с ис- пользованием Visual Studio .NET и одной из самых перспективных техноло- гий программирования, то самое время перейти к изучению материалов этой книги.

ГЛАВА 1

ADO.NET как базовый объект доступа к базам данных

ADO.NET — новый этап в технологии ActiveX Data Objects (ADO, объекты данных ActiveX). Эта модель доступа к данным создана специально для ис- пользования в Web-приложениях. Если раньше в ADO упор делался на по- стоянное соединение с базой данных, то в технологии использования ADO.NET изначально заложена возможность работы приложения в состоя- нии "разрыва" соединения с базой данных. В ADO.NET обеспечивается возможность работы со всеми совместимыми с OLE DB источниками дан- ных как в локальных сетях в рамках традиционных Windows-приложений, так и в глобальных сетях (Интернет) в рамках Web-приложений. Из материалов первой главы вы узнаете:

О

структуру компонента доступа к данным ADO.NET;

 

О

как создать соединение с источником данных — объект connection;

 

О

что такое адаптер данных — объект DataAdapter, и для чего он нужен;

И

первым делом вам предстоит узнать,

как устроен доступ

к данным

в

ADO .NET.

1.1. Структура компонента доступа к данным ADO.NET

Большинство приложений, которые создаются для конечных пользователей, обеспечивают обработку информации, хранящейся в базах данных (склад-

ADO.NET как базовый объект доступа к базам данных

15_

ские, бухгалтерские, торговые, информационно-поисковые системы и т. п.). Это может быть небольшая система, работающая на локальном компьютере, система среднего класса, состоящая из десятка рабочих мест, объединенных локальной сетью, распределенная система, обеспечивающая доступ к дан- ным сотням и тысячам пользователей через сеть Интернет. С точки зрения разработчика желательно иметь единый механизм и единый набор объектов, обеспечивающих доступ к данным, независимо от масштабности решаемой задачи. К счастью в технологии Microsoft .NET создана достаточна гибкая и эффективная модель доступа к данным — ADO.NET, предоставляющая раз- работчикам набор объектов, на основе которых можно создавать приложе- ния любого масштаба (от локальных до глобальных).

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

Независимо оттого, что будет происходить с данными, есть определенные фундаментальные понятия, которые вы должны знать и понимать, если со- бираетесь создавать приложения, обеспечивающие доступ к данным через компонент ADO.NET. Даже если вы лично никогда не будете выполнять некоторые специфические операции, например, редактировать файл XML, содержащий данные, вы должны понимать, как это происходит. Нужно знать архитектуру ADO.NET, составные элементы, их функции, свойства и методы. В данном разделе дается общий обзор наиболее важных понятий. В материале умышленно опускаются многочисленные детали для того, чтобы вы уловили принципиальные возможности новой модели работы приложе- ний с базами данных.

Когда вы распространяете приложения, работающие с данными и созданные в Visual Studio, вы должны убедиться, что у пользователей, использующих ваше приложение, установлен компонент доступа к данным от фирмы Microsoft (MDAC) версии 2.6 и выше.

1.1.1. Работа в отрыве от источника данных

В традиционных системах клиент-сервер при запуске приложения пользовате- лем автоматически устанавливается связь с базой данных, которая поддержива- ется в "активном" состоянии до тех пор, пока приложение не будет закрыто. Такой метод работы с данными становится непрактичным, поскольку подоб- ные приложения трудно масштабируются. Например, такая прикладная систе- ма может работать достаточно быстро и эффективно при наличии 8—10 поль-

16

Глава 1

зователей, но она может стать полностью неработоспособной, если с ней нач- нут работать 100, 200 и более пользователей. Каждое открываемое соединение с базой данных "потребляет" достаточно много системных ресурсов сервера, они становятся занятыми поддержкой и обслуживанием открытых соединений, их не остается на процессы непосредственной обработки данных. При разработке прикладных систем в сети Интернет (Web-приложения) не- обходимо добиваться максимальной масштабируемости. Система должна работать одинаково эффективно как с малым, так и с большим числом пользователей.

По этой причине, в ADO.NET используется модель работы пользователя в отрыве от источника данных. Приложения подключаются к базе данных только на небольшой промежуток времени. Соединение устанавливается только тогда, когда клиент с удаленного компьютера запрашивает на серве- ре данные. После того, как сервер подготовил необходимый набор данных, сформировал и отправил их клиенту в виде WEB-страницы, связь приложе- ния с сервером сразу же обрывается, и клиент просматривает полученную информацию уже не в связи с сервером. При работе в сети Интернет нет необходимости поддерживать постоянную "жизнеспособность" открытых соединений, поскольку неизвестно, будет ли конкретный клиент вообще далее взаимодействовать с источником данных. В таком случае целесооб- разнее сразу освобождать занимаемые серверные ресурсы, что обеспечит обслуживание большего количества пользователей. Программистам, при- выкшим работать с ADO, придется потрудиться над осмыслением новой модели доступа к данным, которая представлена на рис. 1.1.

Рис

.1.1.

Модель доступа

к данным

в ADO.NET

ADO.NET как базовый объект доступа к базам данных

17_

В объектной модели ADO.NET можно выделить несколько уровней.

Уровень данных. Это по сути дела базовый уровень, на котором располага- ются сами данные (например, таблицы базы данных MS SQL Server). На

на маг-

нитных носителях и манипуляция с данными на уровне исходных таблиц (выборка, сортировка, добавление, удаление, обновление и т. п.). Уровень бизнес-логики. Это набор объектов, определяющих, с какой базой данных предстоит установить связь и какие действия необходимо будет вы- полнить с содержащейся в ней информацией. Для установления связи с ба- зами данных используется объект DataConnection. Для хранения команд, выполняющих какие либо действия над данными, используется объект DataAdapter. И, наконец, если выполнялся процесс выборки информации из базы данных, для хранения результатов выборки используется объект DataSet. Объект DataSet, по сути дела, представляет собой набор данных, "вырезанных" из таблиц основного хранилища, который может быть пере- дан любой программе-клиенту, способной либо отобразить эту информацию конечному пользователю, либо выполнить какие-либо манипуляции с полу- ченными данными. Уровень приложения. Это набор объектов, позволяющих хранить и отобра- жать данные на компьютере конечного пользователя. Для хранения инфор- мации используется уже знакомый нам объект DataSet, а для отображения данных имеется довольно большой набор элементов управления (DataGrid, TextBox, ComboBox, Label и т. д.). В Visual Studio .Net можно вести разра- ботку двух типов приложений. В первую очередь это традиционные Windows-приложения (на основе Windows-форм), которые реализованы в виде ехе-файлов, запускаемых на компьютере пользователя. Ну и конечно, Web-приложения (на основе Web-форм), которые работают в оболочке браузера. Как видно из рис. 1.1, для хранения данных на уровне обоих ти- пов приложений используется объект DataSet.

Обмен данными между приложениями и уровнем бизнес-логики происходит с использованием формата XML, а средой передачи данных служат либо

локальная сеть (Интранет), либо глобальная

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

сеть (Интернет).

1.1.2. Взаимодействие с базой данных через команды

В ADO.NET для манипуляции с данными могут использоваться команды, реализованные в виде SQL-запросов или хранимых процедур (DataCommand). Например, если вы хотите получить некий набор информации базы данных, вы формируете команду SELECT или вызываете хранимую процедуру по ее имени.

18

Глава 1

Когда требуется получить набор строк из базы данных, необходимо выпол- нить следующую последовательность действий: открыть соединение (connection) с базой данных, вызвать на исполнение метод или команду, указав ей в качестве параметра текст SQL-запроса или имя хранимой про- цедуры, закрыть соединение с базой данных. Связь с базой данных остается активной только на достаточно короткий срок — на период выполнения запроса или хранимой процедуры. Когда команда вызывается на исполнение, она возвращает либо данные, либо код ошибки. Если в команде содержался SQL-запрос на выборку - SELECT, то команда может вернуть набор данных. Вы можете выбрать из ба- зы данных только определенные строки и колонки, используя объект DataReader, который работает достаточно быстро, поскольку использует курсоры read-only, forward-only.

Если требуется выполнить более чем одну операцию с данными — напри- мер, получить некоторый набор данных, а затем скорректировать его, — то необходимо выполнить последовательность команд. Каждая команда вы- полняется отдельно, последовательно одна за другой. Между выполняемыми командами соединение с базой отсутствует. Например, чтобы получить дан- ные из базы — открывается связь, выбираются данные, затем связь закры- вается. Когда выполняется обновление базы после корректировки инфор- мации пользователем, снова открывается связь, выполняется обновление данных в исходных таблицах и связь снова закрывается. Команды работы с данными могут содержать параметры, т. е. могут исполь- зоваться параметризированные запросы, как, например, следующий запрос:

SELECT

*

FROM customers

WHERE

(custcmer_id=@custoinerid)

Значения параметров могут задаваться динамически, во время выполнения приложения.

1.1.3. Взаимодействие с базой данных через объект DataSet

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

ADO. NET как базовый объект доступа к базам данных

19_

ходной базе данных и заново считывать данные. Более практично работать с некой временной "вырезкой" информации, хранящейся в оперативной па- мяти компьютера.

Эту роль выполняет набор данных — DataSet, который представляет собой своеобразный кэш записей, извлеченных из базового источника. В отличие от привычного Recordset, DataSet может состоять из одной или более таб- лиц, он имеет дело с копиями таблиц из базы данных источника. Кроме того, в данном объекте могут содержаться связи между таблицами и некото- рые ограничения на выбираемые данные. Структура объекта DataSet приве- дена на рис. 1.2.

Рис. 1,2. Структура объекта DataSet

Данные в DataSet — это некий уменьшенный вариант основной базы дан- ных. Тем не менее, вы можете работать с такой "вырезкой" точно так же, как и с реальной базой. Поскольку каждый пользователь манипулирует с полученной порцией информации, оставаясь отсоединенными от основной базы данных, последняя может в это время решать другие задачи. Конечно, практически в любой задаче обработки данных требуется коррек- тировать информацию в базе данных (хотя и не так часто, как извлекать данные из нее). Вы можете выполнить операции коррекции непосредствен- но в DataSet, а потом все внесенные изменения будут переданы в основную базу данных. Важно отметить то, что DataSet — пассивный контейнер для данных, который обеспечивает только их хранение. Что же нужно поместить в этот контейнер, определяется в другом объекте — адаптере данных DataAdapter. В адаптере данных содержатся одна или более команд, ко- торые определяют, какую информацию нужно поместить в таблицы объ- екта DataSet, по каким правилам нужно синхронизировать информацию в конкретной таблице DataSet и соответствующей таблицей основной базы данных и т. п. Адаптер данных обычно содержит четыре команды

добавления, корректировки

SELECT,

INSERT,

UPDATE,

DELETE

для

выборки,

20

Глава 1

Рис. 1.3. Набор команд объекта DataAdapter

кон-

тейнер DataSet, может использовать в элементе SelectCommand следующий запрос:

Например,

метод

Fill

объекта

DataAdapter,

заполняющего данными

SELECT au_id, au_lname, au_fname FROM authors

Набор данных DataSet — "независимая" копия фрагмента базы данных, расположенная на компьютере пользователя. Причем в этой копии могут быть не отражены те изменения, которые могли внести в основную базу данных другие пользователи. Если требуется увидеть самые последние из- менения, сделанные другими пользователями, то необходимо "освежить" DataSet, повторно вызвав метод Fill адаптера данных.

1.1.4. Независимость набора данных DataSet от источника данных

Несмотря на то, что DataSet является фрагментом (кэшем) базы данных, он не имеет постоянной фактической связи с первоисточником. Объект DataSet — это контейнер, заполняемый информацией другим объек- том — адаптером , данных - DataAdapter, который взаимодействует с первоисточником через SQL-запросы или хранимые процедуры. Один объект DataSet может взаимодействовать с несколькими объектами DataAdapter, каждый из которых обеспечивает наполнение данными таблиц контейнера,

Поскольку объект DataSet непосредственно не связан с источником дан- ных, существует хорошая предпосылка для интеграции (объединения) дан- ных, которые поступают из разных источников. Например, часть информа- ции в DataSet может поступить из базы данных центрального офиса компа- нии, часть из базы данных удаленного филиала, или вообще не из базы данных, а из другого источника, например, из электронной таблицы. Как только данные поступят в контейнер DataSet, пользователь может работать с ними как с единым информационным массивом, используя свойства и методы одного объекта, и абсолютно независимо от оригинального источ-

ADO.NET как базовый объект доступа к базам данных

21

ника данных. Схема взаимодействия отсоединенного набора данных DataSet с базой данных приведена на рис. 1.4.

Рис.

1.4. Схема взаимодействия отсоединенного набора данных DataSet с базой данных

1.1.5. Обмен данными в форматеXML

При работе приложений данные должны перемещаться между исходной ба- зой данных и объектом DataSet. В ADO.NET в качестве единого формата для передачи данных используется XML-формат. Аналогично, если данные записать в некий внешний файл, то они будут записаны в XML-формате. Таким образом, файл с данными в формате XML является точно таким же источником, как и любая база данных, и из него можно поместить данные в объект DataSet. Фактически в ADO.NET XML является фундаментальным форматом для данных. В ADO.NET автоматически создают XML-файлы при передаче информации между объектами и компонентами.

Использование обмена данных в едином, формате XML имеет следующие преимущества:

О XML — единый промышленный стандарт, что обеспечивает разработан- ным вами прикладным компонентам обмениваться данными с любыми другими компонентами в любых других приложениях, поскольку все они понимают и используют формат XML;

О XML — обычный текстовый формат. При представлении данных в XML не используется двоичное кодирование, а это обеспечивает возможность передачи данных через любой протокол, например, через HTTP.

При разработке информационных систем вам, как программистам, не по- надобиться знание структуры формата XML. ADO.NET автоматически вы- полнит преобразование данных в XML и из XML-формата так, как потре- буется в текущий момент. Вы же будете взаимодействовать с данными пу-

22

Глава 1

тем использования обычных приемов программирования (через свойства и методы объектов).

1.1.6. Схемы, определяющие структуру данных

Хотя для манипулирования данными (извлекать, записывать, обновлять ин- формацию в базах данных) вам не нужно знать структуру XML-файлов, все же могут возникнуть ситуации, когда необходимо напрямую работать с XML-форматом. Это обычно ситуации, в которых вы не извлекаете и не модифицируете сами данные, а работаете над проектированием структуры набора данных.

Описание набора данных в DataSet представлено с использованием форма- та XML. Для определения количества таблиц, перечня колонок каждой таб- лицы, задания типов данных, ограничений и тому подобного используется XML-схема, которая строится с использованием языка XML Schema Definition Language (XSD). Подобно тому, как данные могут быть загружены в объект DataSet из внешнего XML-источника, так и структура DataSet может быть загружена из XML-схемы.

При разработке большинства приложений нет необходимости углубляться в XML-схемы. Инструментальные средства Visual Studio .NET сами сгенери- руют и скорректируют XML-схемы так, как требуется в текущей ситуации, основываясь на тех действиях, которые делает разработчик в режиме визу- ального дизайнера проекта. Например, когда вы используете окно дизайне- ра для создания объекта DataSet, где представлена одна из таблиц вашей базы данных, то Visual Studio .NET автоматически генерирует XML-схему,

описывающую

Структуру

ЭТОГО

DataSet.

Тем не менее, может настать время, когда вы захотите создать новые или отредактировать существующие схемы самостоятельно. В таком случае, ко- нечно, понадобятся более глубокие знания по данному вопросу. Однако в данной книге обсуждать их нет необходимости.

1.2. Сравнение ADO.NET и ADO

Чтобы лучше понять особенности ADO.NET, сравним этот объект с уже известным нам объектом доступа к данным — ADO.

1.2.1. Представление данных в памяти

В ADO в памяти компьютера данные представлены в виде набора записей

Recordset. В ADO.NET ДЛЯ ЭТОЙ Цели СЛУЖИТ набор Данных DataSet. ЕСТЬ

ADO.NET как базовый объект доступа к базам данных

23

достаточно много важных различий между этими объектами. Остановимся на этих различиях более подробно.

Объект Recordset содержит всего одну таблицу. Если требуется поместить в объекте Recordset информацию из нескольких таблиц базы данных, то предварительно необходимо построить объединяющий SQL-запрос, кото- рый соберет информацию из нескольких таблиц в одну, и данные этой ре- зультирующей таблицы будут помещены в объект Recordset. Часто в ре- зультате объединения нескольких таблиц результирующая таблица доступна только для чтения, и через построенный объект Recordset невозможно об- новлять информацию в исходной базе данных.

В отличие от вышесказанного, объект DataSet представляет собой коллек-

цию (одну или множество) таблиц. Таблицы в пределах набора данных DataSet представляют собой самостоятельные объекты — DataTabie. Если DataSet заполняется информацией из набора таблиц исходной базы дан- ных, то в нем будет сформировано и множество объектов DataTabie. To есть, каждый объект DataTabie обычно соответствует единственной таблице исходной базы данных. Таким образом, DataSet как бы имитирует структу- ру основной базы данных.

В объекте DataSet также могут храниться и реляционные связи между таб-

лицами. Реляционные отношения в пределах DataSet полностью анало- гичны отношениям, построенным по ключевым полям, в исходной базе данных. Например, если объект DataSet содержит таблицы с заказчиками и заказами, то в нем можно сохранить и реляционную связь между заказ- чиками и сделанными ими заказами. Однако реляционные связи между таблицами не переносятся автоматически из основной базы данных, их необходимо создать принудительно (либо на этапе разработки приложе- ния, либо в ходе выполнения приложения). Разработчик имеет возмож- ность либо повторить существующую схему связей между таблицами, либо сформировать иное взаимоотношение между таблицами, чем было в ис- ходной базе данных.

Поскольку DataSet может хранить набор таблиц и набор связей между ни- ми, он является более гибким инструментом, позволяющим представлять пользователям более сложные, иерархические наборы данных, чем объект Recordset.

1,2.2. Навигация по данным и курсоры

В ADO можно получить доступ к требуемым данным, переместившись на

нужную запись объекта Recordset (например, посредством метода MoveNext) и указав номер или имя поля. В ADO.NET представлена коллек- ция таблиц, а каждая таблица, в свою очередь, состоит из коллекции строк

24

;

Глава 1

(записей) и столбцов (полей). Получить доступ к требуемой информации можно путем указания номера (имени) таблицы, номера строки, номера (имени) столбца, В объектах DataRelation содержится информация о роди- тельских и дочерних таблицах и имеется набор методов, обеспечивающих возможность получить доступ к записям дочерней таблицы на основании активного ключа в родительской таблице. Курсор является элементом базы данных, который определяет способ нави- гации по записям, возможность (или невозможность) корректировки дан- ных, и видимость изменений, которые были сделаны в базе данных другими пользователями. ADO.NET не имеет объекта, подобного курсору, но взамен этого представлены элементы, которые имеют то же функциональное на- значение, что и традиционные курсоры в ADO. Например, функциональное назначение одностороннего просмотра данных и доступа только на чтение (forward-only, read-only) обеспечивает объект DataReader.

1.2.3. Минимизация открытых соединений

В ADO.NET связь с базой данных создается только на короткий период времени, достаточный для того, чтобы выполнять такие операции с базой данных, как, например, SELECT или UPDATE. Вы можете за короткий период времени заполнить данными объект DataSet, а затем работать с ними в со- стоянии "отрыва" от источника данных. В ADO объект Recordset так же может обеспечить работу с информацией в состоянии разрыва соединения с источником данных, но ADO изначально оптимизирован для работы в ре- жиме связанного доступа. Есть одно очень значимое различие между разъединенной обработкой в ADO и ADO.NET. В ADO происходит взаимодействие с основной базой данных через OLE DB провайдера. В ADO.NET происходит взаимодействие с базой через некого посредника — адаптера данных (OleDbDataAdapter или SqiDataAdapter). Адаптер данных позволяет контролировать процессы пе- редачи информации из DataSet в исходную базу данных. Например, можно выполнить проверку правильности введенной информации до того, как эти изменения будут переданы источнику данных.

1.2.4. Разделение данных между приложениями

Передача набора данных DataSet между приложениями значительно легче, чем передача набора записей Recordset. Чтобы передавать разъединенный набор Recordset от одного компонента до другого, необходимо использо- вать COM marshalling. Для того чтобы передавать данные в ADO.NET, ис- пользуется DataSet, который передается как XML-файл. Передача данных

ADO.NET как базовый объект доступа к базам данных

25

через XML-файлы имеет ряд преимуществ перед COM marshalling, на кото- рых мы пока останавливаться не будем.

1.3. Соединение с источником данных (объект Connection)

Для перемещения данных между их постоянным хранилищем и приложени- ем, в первую очередь необходимо создать соединение с источником данных (connection). В арсенале ADO.NET для этих целей имеется два объекта:

создать соединения с базами

О

SqlConnection —

объект,

позволяющий

данных MS SQL Server версии 7.0 и выше;

O OleDbConnection — объект, позволяющий создать соединения с любыми источниками данных через OLE DB.

Объект SqlConnection создан и оптимизирован для работы с базами данных

MS SQL Server версии 7.0 и выше. Объект OleDbConnection взаимодейству-

ет с OLE DB и позволяет подключиться к любым источникам данных —

простые текстовые файлы, электронные таблицы, базы данных (включая и

SQL Server).

1.3.1. Строка соединения

Первое свойство, которое необходимо определить для установления связи с базой данных — ConnectionString. Это текстовая строка, которая содержит набор элементов типа атрибут=значение атрибута и служит для определе- ния типа провайдера, имени источника данных (DataSource), имени базы данных (Database), идентификатора пользователя (UserId), пароля доступа (Password), используемой системы безопасности и т. п. Эта строка может выглядеть, например, следующим образом:

MyConnection="Provider=SQLOLEDB.l;DataSource=MySQLServer; InitialCata-

log=NORTHWIND;

Integrated

Security=SSPI"

Перечисленные атрибуты задаются в свойстве ConnectionString объекта, обеспечивающего связь с базой данных (SqlConnection или OleDbConnection). Кроме того, можно также установить свойство ConnectonString в не связанном с приложением udl-файле (Microsoft Data Link file, файл связи данных от Microsoft).

Объект SQLConnection не поддерживает атрибут Provider, поскольку он ра- ботает только с одним провайдером данных.

26

Глава 1

1.3.2. Открытие и закрытие соединения

Объекты connection имеют два базовых метода для открытия и закрытия соединения (open и close). Метод open использует информацию из свойст- ва ConnectionString, чтобы обратиться к источнику данных и открыть (ус- тановить) связь. Метод close закрывает открытое соединение. Закрытие связи приложения с базой данных является очень важным событием. В этот момент освобождаются ценные системные ресурсы, и база данных может обслуживать нового пользователя (количество обслуживаемых пользовате- лей ограничено). Такая экономия особо актуальна для Интернет- приложений, где количество обслуживаемых клиентов может достигать не- скольких сотен и тысяч. Если ВЫ используете объекты DataAdapter или DataCommand, то нет необхо- димости явно открывать и закрывать соединение. Когда вызываются методы этих объектов (например, Fill или update), то автоматически делается про- верка — открыто ли соединение. Если нет, DataAdapter сам откроет соеди- нение, выполнит свои функции и снова закроет соединение. Методы, такие как Fill, открывают и закрывают соединение автоматически только в том случае, если оно не было открыто. Если при вызове подобных методов соединение уже открыто, то оно используется и не закрывается по- сле отработки методов. Такая стратегия дает возможность разработчикам самостоятельно управлять состоянием соединения. Это требуется в тех слу- чаях, когда несколько объектов DataAdapter используют один объект Connection. Тогда более эффективно принудительно открыть соединение и оставлять его открытым, пока не отработают методы всех объектов DataAdapter, после чего принудительно закрыть соединение.

1.3.3. Пул соединений

В Web-приложениях часто множество различных пользователей могут об- ращаться к одной и той же базе и запрашивать одни и те же данные. В этих случаях исполняемое приложение может создать пул соединений к источни- ку данных.

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

Если используется класс OleDbConnection, то пул соединений формируется автоматически провайдером, так что разработчик освобождается от управ-

ADO.NET как базовый объект доступа к базам данных

27_

ления этим процессом. Если используется класс SqlConnection, то создание пула соединений также обеспечивается, но программист имеет возможность вмешиваться в его управление.

1.3.4. Транзакции

Объекты

connection

поддерживают

BeginTransaction,

который

создает

транзакции

с

помощью

объект

OleDbTransactio n

метода

ИЛИ

SqlTransaction. Объекты

позволяют

"откат" назад (RollBack).

ды,

которые

Transaction

вам

завершить

в свою

очередь

поддерживают мето-

сделать

транзакцию (Commit) или

1.3.5. Конфигурирование свойств Connection

Во многих приложениях содержимое объекта connection не может быть однозначно определено на этапе разработки проекта. Например, в прило- жении, которое будет распространяться среди множества клиентов, в connection не могут быть жестко прописаны такие параметры, как имя сервера, имя пользователя или пароль пользователя. У каждого потребите- ля программного продукта значения этих атрибутов будут свои. Следова- тельно, содержимое свойства ConnectionString должно формироваться динамически при запуске приложения. Поскольку динамические свойства соединения заносятся и хранятся в отдельном конфигурационном файле, который не компилируется, то они могут быть впоследствии изменены без перекомпиляции приложения. Динамические свойства автоматически по- лучают значения из конфигурационного файла во время выполнения при- ложения. За работу этого механизма отвечает среда .NET Framework.

Сохранение элементов строки ConnectonString (таких как, например, имя сервера, имя пользователя и пароль) как динамических свойств может иметь смысл и для повышения безопасности вашего приложения.

1.3.6. Объект Connection и безопасность

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

Как вы будете обеспечивать безопасность приложения и порядок доступа из него к источнику данных зависит от архитектуры разрабатываемой системы. В Web-приложениях, например, пользователи обычно получают анонимный доступ к Internet Information Services (IIS), и поэтому не предоставляют ни- каких "сертификатов" на право пользования информацией. В этом случае,

28

Глава 1

ваше приложение должно обеспечивать собственную проверку прав входа в систему, чтобы дать "добро" на открытие соединения и обращения к базе данных. Имя пользователя и пароль могут быть или "прошиты" в откомпи- лированном приложении (в виде значения свойства, установленного во время разработки), или могут быть определены как динамические свойства, которые установлены в файле конфигурации Web-приложения.

Двоичные файлы Web-приложения и файл конфигурации защищены от доступа из сети Интернет собственными средствами защиты ASP.NET, ко- торые предотвращают доступ к этим файлам через любой Интернет- протокол (гипертекстовый транспортный протокол — HTTP, протокол пе- редачи файлов — FTP, и так далее). Чтобы предотвратить доступ к Web- серверу из вашей внутренней сети, необходимо использовать возможности защиты Windows.

В Интранет или в двухуровневых приложениях вы можете использовать ин- тегрированную защиту — средствами Windows, IIS и SQL-сервером. В такой модели защиты для обращения к ресурсам базы данных используются пара- метры идентификации пользователя в сети, а не имя и пароль, заданные в строке соединения. При этом права доступа к информации устанавливаются на сервере базы данных через группы пользователей, так что нет необходи- мости установить индивидуальные параметры разрешения для каждого пользователя, который мог бы обратиться к базе данных. В данной модели вообще не нужно сохранять параметры соединения, и нет необходимости в принятии дополнительных мер по защите параметров строки соединения.

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

Connection в режиме

дизайнера с помощью Server Explorer

Проводник Server Explorer обеспечивает наиболее простой путь создания соединения с источниками данных в режиме дизайнера на этапе проектиро- вания приложения. Здесь программист имеет возможность просмотреть все доступные источники (базы) данных; увидеть таблицы, столбцы и многие другие элементы, а также редактировать и создавать новые элементы базы данных.

Ваше приложение непосредственно не использует соединения, созданные

этим путем.

в режиме

дизайнера при проектировании приложения, используется для того, чтобы задать свойства нового объекта Connection, который вы добавите к вашему

приложению. Иными словами объекты connection, с которыми вы работае- те в окне Server Explorer, являются элементами Server Explorer и служат шаблонами для создания объекта connection, который будет являться эле- ментом формы и реально работать в вашем приложении.

И вообще информация,

поставляемая соединением

ADO.NET как базовый объект доступа к базам данных

29

Например, во время разработки вы задействовали Server Explorer для созда- ния связи (объекта Connection) с SQL-сервером с именем MyServer и базой данных Northwind, которая поставляется вместе с SQL Server. Затем, при проектировании формы, через это соединение вы можете просмотреть структуру базы данных Northwind, выбирать таблицы, выделять нужные вам столбцы и перетаскивать их на форму. Как раз в момент "перетаскивания" элементов из базы данных на проектируемую форму будут автоматически сформированы объекты Connection и DataAdapter. В новое соединение скопируется информация из ConnectionString соединения-шаблона про- водника Server Explorer. Когда разработанное приложение будет запущено на выполнение, то объект connection, расположенный на форме (а не в Server Explorer) будет реально обеспечивать соединение вашего приложения с источником данных.

Информация о соединениях в режиме проектирования приложений хра- ниться на вашем локальном компьютере и не зависит от загруженного в данный момент проекта. Поэтому, как только вы загрузили в Visual Studio какой-либо проект, активизируется объект connection режима проектиро- вания приложений — и вы видите доступные базы данных в проводнике Server Explorer.

1.3.8.Инструменты Visual Studio для создания объектов Connection

Программистам при работе с Visual Studio нет необходимости "руками" формировать свойства объектов connection. Для этого есть соответствую- щие инструментальные средства — например, Мастер Адаптера Данных, который запрашивает у разработчика информацию относительно источника данных и автоматически создает объект connection на форме или на другом компоненте, с которым вы работаете. Однако при желании разработчик можете сам добавить объект connection на форму или другой компонент и задать нужный набор свойств.

1.3.9. Создание объекта Connection в ADO.NET

Для создания

ности:

О Мастера Visual Studio:

объекта

Connection

можно использовать следующие возмож-

Мастер

конфигурации

как

объекта

connection,

элемент,

DataAdapter;

DataAdapter.

необходимый

Этот

для

мастер

создает

формирования

30

Глава 1

• Мастер форм данных — данный мастер создает connection как часть формы, которую он формирует.

O

Путь переноса таблицы, выбранных столбцов таблицы или хранимой процедуры из Server Explorer на форму. При перемещении одного из этих элементов на форму будут автоматически созданы объекты ConnectionИDataAdapter.

O

Создание автономного объекта connection. В этом варианте создается объект connection на форме или компоненте, свойства которого вы конфигурируете вручную. Данный способ можно использовать и тогда, когда вы предпочитаете устанавливать свойства объекта в окне Properties.

O

Создание объекта connection во время работы программы.

Для

создания

щие действия.

автономного

объекта

Connection

нужно

выполнить

следую-

1. Создайте Windows- или Web-приложение (см.

глав 2 и 3).

соответствующие разделы

2. Из вкладки Data панели инструментов Toolbox поместите объект Connection на вашу форму или компонент. Для этого левой кнопкой мыши выделите объект OleDbConnection или SqlConnection (рис. 1.5), затем щелкните левой кнопкой мыши в любом месте формы.

Рис. 1.5. Объекты Connection на вкладке Data окна Toolbox

• Используйте объект

SqlConnection,

если вы будете работать с базой

данных SQL Server версии 7.0 и выше. При этом будет создан объект

Connection с именем SqlConnection, где N— последовательный

номер

(например,

SqlConnectionl).

• Используйте объект OleDbConnection, если вы будете работать с лю- бым другим источником данных, или если тип источника данных в последствии может измениться. При этом будет создан объект

ADO.NET как базовый

объект доступа к базам данных

31

Connection

с именем OleDbConnectionN, где N — последовательный

номер (например, OleDbConnection) .

3. Выделите объект Connection в окне дизайнера, затем в окне Properties модифицируйте значение свойства ConnectionString. Здесь вы можете установить или изменить такие свойства как DataSource, Database, UserName и так далее (вы не сможете переопределить атрибут provider

ДЛЯ Объекта SqlConnection).

Если вы хотите переименовать объект Connection — измените его свойство

Нате.

Если параметры объекта Connection должны быть переустановлены во вре- мя выполнения приложения, то необходимо сконфигурировать свойства объекта connection как динамические. Для этого в окне Properties раскрой- те узел DynamicProperties и щелкните в поле в правой части строки

ConnectionString (рис

1.6) .

Рис.

1.6.

Установление свойств объекта Connection в окне Properties

В открывшемся дополнительном окне Dynamic Propertys установите флажок

Map property to a key in configuration file и нажмите кнопку OK (рис. 1.7).

Рис.

1.7. Установление динамических свойств объекта Connection в окне Dynamic Properly

В результате свойства строки соединения будут помещены во внешний

конфигурационный файл, и их впоследствии можно будет менять без пере- компиляции приложения.

32

Глава 1

1.4. Адаптер данных (объект DataAdapter)

Объект DataAdapter — один из важнейших элементов ADO.NET. Этот объ- ект является посредником между источником данных и набором данных DataSet. В приложениях DataAdapter обеспечивает считывание информа- ции их базы данных и пересылку ее в DataSet, возврат изменений, сделан- ных пользователем, в исходную базу данных. Объект DataAdapter может работать не только с базами данных, он способен связать объект DataSet с любым источником и набором данных.

Вообще, DataAdapter является объектом с перестраиваемой конфигурацией, что позволяет разработчикам задавать, откуда и какую информацию переме- щать в объект DataSet и из него. Задача перемещения данных решается через использование команд на основе SQL-запросов или хранимых процедур.

Visual Studio имеется два типа адаптера данных:

В

O Объект OleDbDataAdapter,

который

используется для работы с любым

источником данных, доступных через OLE DB-провайдера;

O

Объект SqlDataAdapter, который используется для работы с данными, хранящимися в SQL Server версии 7.0 и выше. Поскольку SqlDataAdapter оптимизирован для работы именно с этим источником данных, то он работает с ним более эффективно и быстрее чем

OleDbDataAdapter.

Вы можете создать и управлять адаптерами, используя части .NET Framework, указанные на рис. 1.8.

OleDb Managed Provider Namespace

SqlClient Managed Provider Namespace

Рис. 1.8. Наборы объектов для OleDB-провайдера и SqlClient-провайдера

ADO.NET как базовый объект доступа к базам данных

33_

Каждый объект DataAdapter обеспечивает обмен данными между одной таблицей источника данных (базы данных) и одним объектом DataTabie в наборе данных DataSet. Если DataSet сдержит несколько таблиц (объек- тов DataTabie), то необходимо иметь и несколько адаптеров данных

(рис.1.9).

Рис. 1.9. Взаимодействие адаптеров данных с таблицами базы данных и таблицами объекта DataSet

вызывается соот-

объекта DataAdapter, который по сути дела вы-

полняет SQL-запрос или хранимую процедуру. Также DataAdapter создает

объект чтения данных (OleDbDataReader ИЛИ SqlDataReader), чтобы считать

данные из источника в DataSet. Точно так же, когда необходимо модифи- цировать базу данных, вызывается соответствующий метод (update) объекта DataAdapter, который вызывает на исполнение соответствующий SQL- запрос или хранимую процедуру (рис. 1.9). В результате этого все измене- ния, внесенные пользователем в таблицы набора данных, будут возвращены в соответствующие таблицы базы данных.

Когда требуется заполнить данными таблицу в DataSet,

ветствующий метод

(Fill)

1.4.1. Адаптеры данных и связанные таблицы

Несмотря на то, что в объекте DataSet может быть несколько связанных таблиц, DataAdapter не имеет в SQL-запросах или хранимых процедурах команд (параметров), отражающих эти реляционные связи. Да это и физи-

34

Глава 1

чески невозможно — ведь, как мы уже раньше отмечали, DataAdapter рабо- тает только с одной таблицей в базе данных и с одной таблицей в наборе данных DataSet. Для создания и хранения реляционных связей в DataSet используется другой объект — DataRelation. Кроме возможности создавать

и хранить реляционные связи данный объект позволяет управлять ограни-

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

черней таблице при перемещении по записям в родительской таблице.

Например, представьте, что вам нужно получить данные из двух связанных таблиц базы данных Northwind: Customers и orders ("Клиенты" и "Заказы")

и показать их в одном объекте DataGrid. Раньше для этого понадобилось бы

выполнить объединение этих двух таблиц в одну, например, с использова- нием оператора join в SQL-запросе, чтобы получить единственный набор записей Recordset и затем его связать с DataGrid. Теперь достаточно опре- делить два Объекта DataAdapter один, чтобы заполнить таблицу Customers

("Клиенты") в DataSet и второй, чтобы заполнить таблицу Orders ("Зака- зы"). В DataSet с использованием объекта DataRelation можно указать, что записи таблицы orders связаны с записями таблицы Customers полем CustomerId, после чего связать DataSet с объектом DataGrid. Теперь, имея заполненный объект DataSet и отключившись от исходной базы данных, вы по своему желанию можете работать как с каждой таблицей отдельно, так и, вызвав необходимые свойства и методы объекта DataRelation, со связанной парой таблиц. Этого в принципе невозможно было сделать с объектом Recordset, так как он заполнялся информацией из уже объединенного на- бора записей. Такая возможность является неоспоримым преимуществом Объекта DataSet над объектом Recordset.

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

DataAdapter использует объекты OleDbConnection ИЛИ SqlConnection, ЧТО-

бы связаться с источником данных. DataAdapter может одновременно под- держивать до четырех открытых соединений, по одному для каждого типа действия, которое он может выполнить: SELECT, UPDATE, INSERT и DELETE. Объект OleDbConnection обеспечивает соединение с любым источником данных OLE DB-провайдера. Объект SqlConnection обеспечивает соедине- ние с SQL Sewer 7.0 и выше. В обоих случаях, объект Connection представ- ляет уникальный сеанс соединения с источником данных.

1.4.2. Адаптеры данных и объекты Command

Используя объект DataAdapter, можно читать, добавлять, модифицировать

и удалять записи

Чтобы определить, как каждая из

в источнике данных.

ADO.NET

как

базовый

объект

доступа

к

базам

данных

_

35_

этих

четыре свойства:

O SelectCommand —

операций

должна

произойти,

DataAdapter

которая

которая

поддерживает следующие

обеспечивает

выборку

обеспечивает

добавление

команды, нужной информации из базы данных;

описание записей в базу данных;

описание

O InsertCommand —

команды,

O UpdateCommand — описание команды, записей в базе данных;

команды,

O DeleteCommand —

описание записей из базы данных.

которая обеспечивает обновление

которая

обеспечивает

удаление

Каждая из этих команд реализована в виде SQL-запроса или хранимой про- цедуры.

Эти свойства являются самостоятельными объектами и относятся к элемен- там класса OleDbCommand или SqlCommand. Данные объекты поддерживают свойство CommandText, содержащее описание SQL-запроса или хранимой процедуры.

Класс объекта Command должен согласовываться с классом объекта Connection. Например, если вы используете объект SqlConnection, чтобы

связаться с SQL-сервером, то нужно использовать команды, которые происхо-

дят от класса

SqlCommand.

Разработчик приложения может самостоятельно сформировать текст OleDbCommand или SqlCommand, хотя чаще в этом нет необходимости, по- скольку Visual Studio автоматически генерирует необходимые инструкции SQL при создании объекта DataAdapter. Кроме того, DataAdapter может автоматически генерировать SQL-запросы во время выполнения приложе- ния, если объекты UpdateCommand, InsertCommand ИЛИ DeleteCommand не определены на этапе проектирования приложения. Например, вы можете создать или изменить содержимое команды выборки данных, связанной объектом SelectCommand, непосредственно перед тем, как она будет запу- щена на выполнение.

В Visual Studio также имеется возможность выполнять команды независимо от объекта DataAdapter. Например, когда нет необходимости возвращать набор данных (проверка прав доступа пользователя к базе данных) или ко- гда требуется изменить структуру некоторых таблиц. В этом случае обеспе- чивается возможность прямой работы с таблицами базы данных на уровне •SQL-сервера с удаленных компьютеров, как через локальную сеть, так и через Интернет.

36

Глава 1

Команды в DataAdapter могут иметь параметры. Например, команда выборки информации (SelectCommand), обычно имеет параметры в предложении WHERE, для того, чтобы получить из базы данных содержимое не всей таблицы, а только записей, соответствующих определенным критериям. Другие команды (например, UpdateCommand) используют параметры для выделения только тех записей в базе данных, которые необходимо модифицировать.

1.4.3. Чтение и обновление данных с использованием объекта DataAdapter

Основная задача, которую должен решать объект DataAdapter — это пере- мещение информации между основным хранилищем данных на сервере и набором данных DataSet в памяти компьютера пользователя. Объект DataAdapter имеет методы, позволяющие переместить данные между этими двумя компонентами в прямом и обратном направлениях.

Если в приложении требуется только прочитать данные из базы для просмотра (не модифицируя их), то нет необходимости помещать их в объект DataSet . Для этого случая имеется возможность считать информацию в режиме read only непосредственно из базы данных в приложение с помощью объек- та DataReader, о чем более подробно будет сказано ниже.

Вы можете использовать DataAdapter для выполнения следующих операций.

O Перемещение записей из таблицы базы данных в соответствующую таб- лицу объекта DataSet;

Для этих целей используется метод Fin объектов SqlDataAdapter или OleDbDataAdapter. Когда вызывается этот метод, происходит обращение к базе данных с использованием SQL-запроса на основе инструкции SELECT;

объекта

O Передача

изменений,

сделанных

пользователем

в

таблице

DataSet, исходной таблице базы данных.

для этих целей используется метод Update объектов SqlDataAdapter ИЛИ OleDbDataAdapter. Когда вызывается такой метод, происходит обращение к базе данных с использованием SQL-запроса на основе инструкций INSERT, UPDATE или DELETE, в зависимости оттого, что сделал пользователь — доба- вил, изменил или удалил некоторые записи.

Если в приложении необходимо только получить данные для последова- тельного просмотра (в режиме read-only), то можно использовать объект DataReader вместо объекта DataSet. Объект DataReader выбирает информа-

ADO. NET как базовый объект доступа к базам данных

37

цию из источника (базы) данных и передает ее непосредственно вашему приложению. Как правило, объекты DataReader используются для быстрого просмотра данных в режиме read-only, forward-only, когда не требуется кор- ректирование информации. Например, имеется страница Web-формы, кото- рая просто отображает информацию, полученную из базы данных. По- скольку на Web-форме страница будет обновляться при каждом обращении к источнику данных, то нет необходимости помещать информацию в объект DataSet. Следует отметить, что объект DataAdapter тоже обращается к объ- екту DataReader для заполнения набора данных DataSet. В Visual Studio Имеется Два объекта чтения данных — OleDbDataReader И SqlDataReader, используемых соответственно для OLE DB-источников данных и для SQL Server версии 7.0 и выше.

В Visual Studio при создании набора данных имя результирующей таблицы в объекте DataSet (как и имена колонок) формируется на основе соответст- вующих имен исходной таблицы источника (базы) данных. Это может быть не совсем удобно как для разработчика, так и для конечного пользователя, поскольку названия колонок может быть слишком длинным или наоборот коротким и малоинформативным. В таком случае естественно возникает желание сменить соответствующие имена и сделать их более понятными и удобными в работе. В Visual Studio разработчики имеют возможность задать новое имя таблицы, создаваемой в DataSet, и новые имена колонок в ко- манде формирования набора данных, а также привести их в соответствие с теми именами, которые используются в базе данных. В объекте DataAdapter имеется коллекция свойств TableMappings, которые обеспечивают поддерж- ку соответствия между названиями элементов (таблиц и колонок) в DataSet и именами соответствующих элементов основного хранилища данных.

1.4.4. Параметры команд объекта DataAdapter

Команды адаптера данных DataAdapter определены в свойстве CommandText Объектов SelectCommand, InsertCommand, UpdateCommand И DeleteCommand. Обычно в этих командах содержится такие элементы, как параметры. Ведь заранее неизвестно, например, какие записи будет удалять или обновлять пользователь, это станет ясно только в процессе работы приложения. При- чем в каждом сеансе набор этих записей будет различным.

Можно выделить два типа параметров.

O Параметры выборки. В реальных приложениях обычно требуется вы- брать только некоторое подмножество записей из базы данных. Чтобы осуществить это, используется SQL-запрос или хранимая процедура, ко- торые включают предложение WHERE с параметрами — критериями вы- борки. Кроме того, когда пользователь модифицирует или удаляет за- пись, используется предложение WHERE, в котором параметры определя-

38

Глава 1

ют, какие записи необходимо модифицировать или удалить. Значения параметров становятся известными только во время выполнения прило- жения, поэтому разработчик не может их заранее однозначно задать в программе.

O Параметры обновления. Когда в приложении модифицируются сущест- вующие записи или добавляются новые, то колонки (поля) в модифи- цируемых или добавляемых записях, должны получить новые значения. Чаще величина этих значений также становится известной только во время выполнения приложения.

Параметры выборки

Когда требуется выбрать ограниченное подмножество записей, чтобы за- полнить таблицу в объекте DataSet, в предложение WHERE SQL-запроса включается один или более параметров, значения которых определяются только во время выполнения приложения. Например, пользователь хочет найти в базе данных книгу, название которой он ввел в текстовом поле Web-формы. Для этого вы должны в свойстве CommandText объекта SelectCommand написать SQL-запрос. Параметры запроса можно определить следующими способами: вопросительным знаком (?) или переменной с именем параметра (перед именем параметра должен стоять знак @). Для обозначения параметров в запросах на основе объектов OleDbCommand ис- пользуются вопросительные знаки; в запросах на основе объектов SqlCommand использует переменные с именем параметра.

Текст запроса для объекта OleDbCommand может выглядеть следующим образом:

SELECT BookId, Title, Author, Price FROM BOOKS WHERE (Title LIKE ?)

Соответственно текст запроса для объекта SqlCommand:

SELECT BookId, Title, Author, Price FROM BOOKS WHERE (Title LIKE @title)

В приложении вы даете возможность пользователю ввести значение пара- метра запроса (наименование книги — title) , например, в текстовом поле, затем присваиваете полученное значение параметру:

OleDbDataAdapterl.SelectCommand.Parameters("title").Value=txtTitle.Text

После этого запускаете команду на выполнение.

В Visual Studio можно формировать SQL-запросы с параметрами, используя встроенное средство Query Builder (построитель запросов).

Параметры обновления

Если объект SelectCommand адаптера данных может иметь или

раметры,ТОобъектыUpdateCommand,InsertCommandИDeleteCommandвсегда имеют параметры.

не иметь па-

ADO,NET как базовый объект доступа к базам данных

39

Такие команды как UpdateCommand И InsertCommand всегда требуют наличия параметра для каждого столбца, который будет модифицирован. Кроме то- го, UpdateCommand и DeleteCommand требуют наличия параметра и в пред- ложения WHERE, который будет идентифицировать те записи, в которые бу- дут вноситься изменения.

Представим приложение, с помощью которого пользователи могут заказы- вать и покупать книги. Как и обычные покупатели в магазине, они имеют тележку для выбранных книг, которая в приложении реализована в виде таблицы данных — ShoppingCart. В таблице ShoppingCart пользователи заводят новые записи под каждую книгу, которую они хотят купить, с атри- бутами: идентификатором книги (BookId) и идентификатором клиента (CustId), которые совместно выступают в роли ключа, однозначно иденти- фицирующего каждую запись в таблице ShoppingCart.

Когда пользователь кладет новую книгу в тележку для покупок, он фактиче- ски добавляет запись в таблицу ShoppingCart. В приложении эту процедуру

В этом

можно реализовать с помощью SQL-запроса с инструкцией INSERT. случае SQL-запрос выглядит следующим образом:

INSERT INTO ShoppingCart (BookId, CustId, Quantity) Values (?, ?, ?}

Три вопросительных знака в тексте запроса представляют собой параметры, значения которым будут присвоены во время выполнения приложения, со- ответственно после отработки запроса значения параметров будут переданы в колонки BookId, CustId, Quantity новой записи таблицы ShoppingCart. Если использовать переменные с именами параметров, тот же самый запрос будет иметь вид:

INSERT

@custid,

INTO ShoppingCart

@quantity)

(BookId,

CustId,

Quantity)

Values

(@bookid,

Если пользователь решает что-нибудь изменить в уже сделанной покупке, например, количество книг, то эту процедуру можно реализовать в прило- жении с помощью SQL-запроса на обновление, содержащего инструкцию UPDATE. Такой запрос может иметь следующий вид:

UPDATE

ShoppingCart

 

SET

(BookId=?,

CustId=?,

Quantity=?)

WHERE

(BookId=?

AND

CustId=?)

Или, при использовании переменных с именем параметра:

UPDATE ShoppingCart SET(BookId=@bookid, CustId=@custid, Quantity=@quantity) WHERE (BookId=@bookid AND CustId=@custid)

В этом SQL-запросе параметры в предложении SET используются для за- полнения новыми данными соответствующих колонок в таблице

40

Глава 1

ShoppingCart. Параметры в предложении WHERE выделяют тот набор запи- сей, в которых произойдет обновление данных. Пользователь может также удалить книгу из тележки для покупок. В том случае приложение могло бы вызвать SQL-запрос на удаление с предложе- нием DELETE следующего типа:

DELETE

FROM

ShoppingCart

WHERE

(BookId=?

AND CustId=?)

Или для переменных с именем параметра:

DELETE FROM ShoppingCart WHERE (BookId=@bookid AND CustId =@custid)

Коллекция параметров

Для обеспечения возможности передачи значений параметров из приложе- ния в запрос во время выполнения программы, каждый из четырех объектов (SelectCommand, InsertCommand, UpdateCommand И DeleteCommand) объекта DataAdapter поддерживает свойство Parameters, которое содержит коллек- цию параметров, соответствующих параметрам SQL-запроса. В командах для объекта OleDbDataAdapter индивидуальные параметры обозначаются, как OleDbParameter В Коллекции параметров OleDbParameterCollection. По аналогии команды в объекте SqlDataAdapter имеют обозначение пара- метров SqlParameter в коллекции SqlParameterCollection.

Если вы используете мастера конфигурации адаптера данных (Data Adapter Configuration Wizard), чтобы сконфигурировать объект DataAdapter, то кол- лекция параметров создается автоматически для всех четырех команд (SelectCommand, InsertCommand, UpdateCommand И DeleteCommand). Если ВЫ перетаскиваете элементы из Server Explorer на форму или компонент, то Visual Studio может выполнить следующие действия:

O Если вы перетаскиваете таблицу или некоторые колонки таблицы в ок- но дизайнера формы, то Visual Studio генерирует объект SelectCommand (SQL-запрос с инструкцией SELECT) без параметров и параметризован- ные объекты UpdateCommand, InsertCommand И DeleteCommand. Если ВЫ хотите, чтобы SQL-запрос объекта SelectCommand имел параметры, вы должны конфигурировать их вручную.

O Если вы перемещаете хранимую процедуру в окно дизайнера формы, то Visual Studio генерирует объект SelectCommand с параметрами, как и требуется для хранимой процедуры. Однако если вы нуждаетесь в других Объектах (UpdateCommand, InsertCommand И DeleteCommand), ВЫ ДОЛЖНЫ сконфигурировать их самостоятельно, вручную задав их параметры.

Наиболее рациональный путь создания параметризированных запросов для объекта DataAdapter — использование мастера Data Adapter Configuration Wizard. После работы мастера, если необходимо, можно изменить конфигу- рацию параметров вручную в окне Properties.

ADO.NET как базовый объект доступа к базам данных

41_

Структура коллекции

Parameters

Каждый элемент коллекции параметров в объектах Command (SelectCommand,

UpdateCommand,

DeleteCommand) соответствуют параметру

InsertCommand И

SQL-запроса, записанного в свойство CommandText. Если объект command представляет собой SQL-запрос с параметрами в виде знаков вопроса, то каждый элемент в коллекции параметров будет соответствовать одному во- просительному знаку в SQL-запросе. Например, следующая инструкция за- проса на обновление UPDATE требует коллекции из пяти параметров:

UPDATE ShoppingCart

SET (BookId=?, CustId=?, Quantity=?) WHERE (BookId=? AND CustId=?)

Аналогично для именованных параметров:

UPDATE ShoppingCart SET (BookId=@bookid, CustId=@custid, Quantity=@quantity)

WHERE (BookId=@bookid AND CustId=@custid)

Если объект command ссылается на хранимую процедуру, то номер элемента параметра в коллекции определяется процедурой. В хранимых процедурах параметры могут также иметь имена. В этом случае позиция параметра в коллекции не имеет значения. Каждый элемент параметра в коллекции имеет свойство ParameterName, которое используется для согласования с соответствующим параметром в хранимой процедуре. Если вы формируете коллекцию параметров вручную, то необходимо точно знать, какие параметры требуются для корректной работы хранимой проце- дуры. Многие хранимые процедуры возвращают значение. В таком случае возвращаемое значение передается назад вашему приложению через кол- лекцию параметров, и вы должны учесть это. Кроме того, часто хранимые процедуры состоят из множества SQL-запросов, и вы должны убедиться, что коллекция параметров содержит все значения, которые необходимы всем запросам в процедуре. Если параметры не имеют имен (в хранимых процедурах), то элементы кол- лекции имеют такую же нумерацию и расположение, как и параметры в хранимой процедуре. Если хранимая процедура возвращает значение, то первый элемент в коллекции параметров (нулевой элемент) зарезервирован для этого возвращаемого значения. Поэтому для доступа к индивидуальному параметру коллекции можно со- слаться на его индекс (номер) в коллекции. Однако если в объекте поддер- живается свойство имя параметра (ParameterName), то возможен доступ к параметру по его имени. В листинге 1.1 приведен пример SQL-запроса на Visual Basic и С#. Вторая и третья строка запроса эквивалентны при усло- вии, что второй параметр в коллекции имеет имя Title_Keyword.

Глава 1

Листинг 1.1

' Visual Basic

titleKeyword="%" & txtTitleKeyword.Text & "%"

OleDbDataAdapter1.SelectCommand.Parameters(1).Value=titleKeyword

OleDbDataAdapter1.SelectCommand.Parameters("TitleKeyword").Value = titleKeyword

// C#

string

this.OleDbDataAdapter1.SelectCommand.Parameters[1],Value=titleKeyword;

titleKeyword="%"+txtTitleKeyword.Text+"%";

titleKeyword="%"+txtTitleKeyword.Text+" %";

this.OleDbDataAdapter1.SelectCommand.Parameters["TitleKeyword"].Value=

titleKeyword;

Здесь в первом случае программа присваивает значение параметру, ссылаясь на его номер в коллекции — 1, во втором случае — на его имя. Использо- вание имени параметра в практике программирования более предпочти- тельно, чем индекса. При использовании имени уменьшается потребность в переписывании кода, если в ходе работы над проектом вдруг меняется ко- личество параметров, а также отпадает необходимость помнить, возвращает ли хранимая процедура значение.

Для того чтобы получить доступ к имеющейся коллекции параметров, нуж- но в окне Properties найти свойство Parameters для интересующей вас ко- манды. Например, на рис. 1.10 представлена строка доступа к параметрам команды адаптера данных InsertCommand для таблицы customers базы дан- ных Northwind.

Рис.

1.10.

Строка доступа к коллекции параметров команды InsertCommand

Если щелкнуть кнопку на поле (Collection) в строке Parameters, то откроет- ся диалоговое окно редактирования свойств коллекции параметров

ADO.NET как базовый объект доступа к базам данных

43

В этом окне разработчик приложения имеет возможность изме-

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

(рис. 1.11).

Рис. 1.11. Окно редактирования свойств параметров команды InsertCommand

Установление значений

параметров

Есть два способа, с помощью которых можно задать значения параметров:

O явным заданием значений параметрам через свойство value;

O располагая (добавляя) параметры в колонки таблицы объекта DataSet.

Вы устанавливаете значения параметров явно, когда заполняете набор дан- ных или вызываете команду (для параметров выбора). Например, в примере поиска книг, приведенного выше, в приложении есть текстовое поле, в ко- торое пользователь вводит ключевое слово (название книги). В этом случае можно явно установить значение параметра, привязав его к свойству Text текстового поля перед вызовом метода Fill объекта DataAdapter. Пример программного кода такого способа приведен в листинге 1.2.

44

Глава 1

| Листинг 1.2

' Visual Basic

titleKeyword="%" a txtTitleKeyword.Text & "%"

OleDbDataAdapter1.SelectCommand.Parameters("TitleKeyword").Value

titleKeyword

OleDbDataAdapter1.Fill(dsAuthors1)

// C#

=

titleKeyword OleDbDataAdapter1.Fill(dsAuthors1) // C# = titleKeyword="%"+txtTitleKeyword.Text+"|";

titleKeyword="%"+txtTitleKeyword.Text+"|";

this.OleDbDataAdapter1.SelectCommand.Parameters["TitleKeyword"].Value=^>

titleKeyword;

this.OleDbDataAdapter1.Fill(dsAuthors1);

Параметры должны получить значения и в случаях обновления данных. Ко- гда вызывается метода update объекта DataAdapter, то осуществляется про- смотр всех записей таблицы набора данных DataSet, и модификация запи- сей базовой таблицы (update, insert, delete) происходит на основе значе- ний, полученных из соответствующих . колонок каждой записи. То есть параметры получают свои значения из колонок записи набора данных DataSet. Например, если в таблице объекта DataSet была добавлена новая запись и активизирована команда InsertCommand на вставку строки в ос- новную таблицу базы данных, то значения параметров для предложения INSERT этой команды будут считаны из колонок той записи, которая была добавлена в таблицу объекта DataSet. Таков типичный сценарий работы команд обновления данных, но не единственный. Хранимые процедуры то- же могут возвращать данные через коллекцию параметров или через воз- вращаемое значение. В этом случае возвращенные значения должны быть "привязаны" к соответствующим колонкам таблицы набора данных DataSet.

Параметры обновления также возможно задать явно. Объект DataAdapter поддерживает событие RowUpdating, которое вызывается каждый раз, когда происходит обновление записи. Вы можете создать обработчик данного со- бытия и в нем явно присвоить параметрам нужные значения. Это обеспечи- вает жесткий контроль, над значениями параметров и позволяет переназна- чать их динамически в ходе работы программы непосредственно перед об- новлением записи в таблице исходной базы данных.

1.4.5. Свойство TableMappings объекта DataAdapter

Когда DataAdapter считывает записи из источника данных, должно быть определено, как, разместить полученную информацию в соответствующей

ADO. NET как базовый объект доступа к базам данных

45

таблице объекта DataSet. Это определяется схемой таблицы (table mapping).

В такой схеме связываются между собой имена колонок таблицы источника

данных с именами колонок таблицы набора данных DataSet. Например, информация из колонки с именем au_id в таблице источника данных мо- жет принадлежать колонке с именем author_id_number в таблице объекта DataSet.

По умолчанию, когда Visual Studio генерирует объект DataSet, элементы набора данных (таблицы и колонки) имеют те же самые имена, что и в ис- точнике данных. Однако в некоторых ситуациях имена в источнике данных

и

наборе данных DataSet могут не совпадать.

 

O

Набор

данных

был

создан

на

основе

существующей

схемы,

в

которой

использовались различные имена.

 

O

Разработчик

изменил

имена элементов

набора данных для

удобочитае-

мости, для перевода наименований с одного языка на другой другой причине.

или

по

Сформировать или модифицировать структуру таблицы можно, используя

свойство TableMappings адаптера данных, которое включает в себя коллек- цию элементов DataTableMapping. Есть только один объект DataTableMapping для каждой отображаемой таблицы, потому что DataAdapter связывает только единственную исходную таблицу и единст- венную таблицу набора данных. Доступ к этому свойству можно получить

из окна Properties объекта DataAdapter (рис. 1.12).

Рис. 1,12. Строка доступа к свойству TableMappings

При нажатии на кнопку в поле (Collection) свойства TableMappings появля- ется диалоговое окно, позволяющее редактировать элементы коллекции DataTableMapping (рис. 1.13). Здесь содержатся свойства для идентифика- ции таблицы источника данных и таблицы набора данных, а так же свойст-

46

Глава 1

во ColumnMappings, содержащее элементы, которые представляют колонки соответствующих таблиц.

Рис.

1.13. Диалоговое окно Table Mappings

Когда происходит вызов метода Fin объекта DataAdapter, то выполняются следующие действия, в результате которых таблица объекта DataSet запол- няется данными.

в

1. Адаптер данных

ищет название каждого столбца исходной таблицы

объекте TableMappings.

2. Когда адаптер данных находит название столбца исходной таблицы, то получает название соответствующего ему столбца таблицы набора дан-

ных.

3. Получив имена этих двух столбцов, DataAdapter переносит данные от

в соответствующий столбец табли-

исходного столбца базовой таблицы цы набора данных DataSet.

Есть две причины, которые могут воспрепятствовать данному процессу.

O Не найдена информация об исходном столбце. Это может произойти потому, что он не описан в схеме таблицы (например, разработчик из-

ADO.NET как базовый объект доступа к базам данных

 

менил

структуру

исходной

таблицы

базы данных

после того,

как был

Сформирован Объект DataAdapter).

 

O

Столбец,

в

который

нужно

переместить данные,

не определен

в схеме

набора данных.

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

O

Passthrough — адаптер пытается загрузить данные исходного столбца в столбец с тем же именем набора данных. Если в наборе данных нет столбца с аналогичным именем, поведение программы в дальнейшем будет зависеть от параметров свойства MissingSchemaAction (см. ниже);

O

Ignore — столбцы,

которые должным образом

не описаны

в

схеме,

не

загружаются данными и остаются пустыми;

O Error - генерируется ошибка.

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

O

Add таблица или столбец добавляются к схеме и к набору данных;

 

O

AddWithKey— таблица или

столбец добавляются

к

набору данных

и

к

схеме, причем добавленный столбец делается ключевым;

 

O

Ignore

— таблица или столбец,

не представленные

в схеме набора дан-

ных не добавляются к набору данных;

O

Error — генерируется ошибка.

Необходимо установить оба этих свойства, чтобы обеспечить устойчивость работы приложения. Например присвоение свойству MissingMappingAction значения Passthrough И свойству MissingSchemaAction значения Add обес- печит эффект автоматического дублирования таблицы источника в наборе данных DataSet. Можно настроить свойства таким образом, что приложение будет генериро- вать ошибку, если есть какое-то несоответствие между базовой таблицей и схемой набора данных, что предотвратит некорректную обработку инфор- мации.

48_

Глава 1

Если задается режим игнорирования ошибки, то обеспечивается гарантиро- ванная загрузка тех данных, которые явно определены в схеме или отобра- жены в свойстве TableMappings. Это полезно использовать тогда, когда адаптер данных обращается к хранимой процедуре или SQL-запросу, кото- рые возвращают больше столбцов, чем определено в наборе данных DataSet.

1.4.6. Созданиеобъекта DataAdapter

Объект DataAdapter может быть создан следующими способами:

O

с использованием Server Explorer;

O

с

использованием

мастера;

O

вручную.

Рассмотрим все эти возможности.

Создание объекта DataAdapter с использованием Server Explorer

Для создания объекта DataAdapter с использованием Server Explorer по- стройте Windows или Web-приложение (см. соответствующие разделы глав 2 и 3), а затем выполните следующие действия.

1. Создайте или откройте форму в соответствующем приложении, активи- зируйте окно дизайнера формы и перейдите в окно Server Explorer.

2. Если нужный вам объект Connection отсутствует, то создайте его.

3. Откройте объект Connection и войдите в нужный вам элемент этого объекта (Tables, Stored Procedures, Views или Functions). Если, например, вам нужна не вся таблица, а только некоторые колонки, то раскройте следующий уровень и получите доступ к набору колонок таблицы. '

Если вы выбрали хранимые процедуры, то затем вам необходимо будете вруч- ную сформировать команды UpdateCommand, InsertCommand И DeleteCommand после создания объекта DataAdapter.

4. Выберите одну или более колонок таблицы или хранимой процедуры и перетащите их мышью в окно дизайнера формы (рис. 1.14).

Вместо колонок можно перетащить всю таблицу, при этом будет сформиро- ван запрос типа SELECT * FROM имя_таблицы. С точки зрения разработчика

ADO.NET как базовый объект доступа к базам данных

49

такой путь, конечно, проще. Однако если для конкретной формы требуются не все колонки таблицы, то отбор индивидуальных колонок более предпочтите- лен и эффективен, потому что уменьшается объем данных, передаваемых по каналу связи.

Рис.

1.14. Таблица Customers в окне Server Explorer

После этого Visual Studio автоматически создаст два объекта connection И DataAdapter (рис. 1.15).

Рис. 1.15. Объекты SqlConnectionl и SqlDataAdapter1, созданные из окна Server Explorer

50

Глава 1

Если в качестве источника информации использовалась таблица базы данных, то в объекте DataAdapter будут сформированы команды для чтения и обновления данных. Если в качестве источника была взята хра- нимая процедура, то будут сформированы команды только для чтения данных. Перетаскивание элементов данных из окна Server Explorer на проектируе- мую форму наиболее легкий путь создания объекта DataAdapter, однако он не дает возможности создать параметризованный запрос или новые храни- мые процедуры. Для этого можно использовать мастер Data Adapter Configuration Wizard.

Создание объекта DataAdapter с использованием мастера

Мастер Data Adapter Configuration Wizard обеспечивает достаточно простой и самый гибкий способ создания адаптера данных.

Для создания объекта Data Adapter с помощью мастера постройте Windows или Web-приложение (см. соответствующие разделы глав 2 и 3) и выполни- те следующие действия.

1. Создайте или откройте форму в соответствующем приложении и акти- визируйте окно дизайнера формы.

2. Из вкладки Data окна Toolbox перенесите объект OleDbDataAdapter или SqlDataAdapter в область дизайнера формы (рис. 1.16).

Рис.

1.16. Выбор объекта DataAdapter в окне Toolbox

После этого Visual Studio добавит соответствующий объект DataAdapter к форме и запустит мастер Data Adapter Configuration Wizard.

3. В мастере последовательно выполняются следующие шаги:

• На второй странице (рис. 1.17) создайте или выберите существующий

объект

Connection.

ADO.NET как базовый объект доступа к базам данных

51

Рис. 1.17. Выбор или создание объекта Connection в мастере конфигурации объекта DataAdapter

На третьей странице (рис. 1.18) определите, должен ли адаптер дан- ных использовать SQL-запрос или хранимую процедуру (значения переключателей приведены в табл. 1.1).

Рис. 1.18. Выбор способа получения записей из базы данных объектом DataAdapter

52

Глава 1

Таблица 1.1. Значения положений переключателя способа получения записей из базы данных объектом DataAdapter

Переключатель Описание

Use SQL statement Создается SQL-запрос на основе предложения SELECT, который DataAdapter будет использовать для заполне- ния данными результирующей таблицы объекта DataSet, а также мастер сгенерирует запросы на основе предложений UPDATE, INSERT и DELETE для обновления данных в исходной таблице базы данных

Use newly created stored

Определяется запрос на основе предложения SELECT, и

procedures мастер создает хранимую процедуру для чтения и об- новления источника данных. Если поставщик данных не поддерживает этот параметр, то он будет недоступен

Use existing stored proce- Определяется существующая хранимая процедура, ко-

dures

торую DataAdapter будет использовать для чтения и обновления источника данных

Что появится в следующей странице мастера, будет зависеть от сделан- ного выбора (в данном случае мы выберем переключатель Use SQL statement).

На

четвертой

странице

(рис.

ных с предложением SELECT.

1.19)

создается

запрос

на

выборку дан-

Рис. 1.19. Создание запроса к базе данных в мастере конфигурации объекта DataAdapter

ADO.NET как базовый объект доступа к базам данных

53

На этой странице можно либо просто набрать текст SQL-запроса, либо использовать мастер построения запросов, для запуска которого необхо- димо нажать кнопку Query Builder. При вызове мастера построения за- просов появится дополнительное окно (рис. 1.20) с предложением вы- брать одну из таблиц базы данных.

Рис. 1.20. Окно Add Table построителя запросов в мастере конфигурации объекта DataAdapter

В построителе запросов можно выбрать требуемую таблицу, указать пе- речень необходимых колонок, сконфигурировать параметры запроса, за- дать условия сортировки. Можно также выполнить запрос и посмотреть возвращаемые им данные (рис. 1.21).

После нажатия кнопки ОК мастер завершит свою работу, а текст по- строенного запроса будет передан мастеру конфигурирования адаптера данных (рис. 1.22).

Нажав на кнопку Next, мы перейдем на информационную страницу мастера (рис. 1.23), где выведен перечень элементов, созданных в ре- зультате работы мастера. Если мастеру, по каким-либо причинам не уда- лось создать некоторые элементы, они будут помечены соответствующими

54

Глава 1

Рис. 1.21. Работа в окне мастера построения запросов

Рис. 1.22. Текст созданного SQL запроса в мастере конфигурации объекта DataAdapter

ADO.NET как базовый объект доступа к базам данных

55

Рис, 1.23. Перечень элементов, созданных в результате работы мастера конфигурации объекта DataAdapter

предупреждающими значками. В нашем случае против каждого элемента стоит отметка о его успешном создании.

Когда

мастер

закончит

свою

работу

кроме

объекта

DataAdapter

будет

по-

строен

и

объект

connection,

который

был

определен

на

второй

странице

мастера.

Если вы хотите изменить название объектов DataAdapter и connection, вы- берите мышью нужный объект и задайте удобное для вас имя в окне Properties.

Если вы хотите посмотреть, какие данные DataAdapter перенесет в набор данных DataSet, то можно запустить мастера предварительного просмотра данных. Для этого нужно в меню Data выбрать пункт Preview Data и в от- крывшемся диалоговом окне Data Adapter Preview нажать кнопку Fill DataSet (рис. 1.24).

Вы также имеете возможность переконфигурировать адаптер DataAdapter вручную. Для этого нужно модифицировать схему данных. Выполнение та- кой процедуры рассматривается в следующем разделе.

56

Глава 1

Рис. 1.24. Предварительный просмотр данных, представляемых объектом DataAdapter

Создание и конфигурирование объекта DataAdapter вручную

Бы можете создать объект DataAdapter вручную, без использования со-

каким способом

был создан DataAdapter, всегда имеется возможность изменить его кон-

фигурацию.

Для

следующие действия.

ответствующего мастера.

создания

объекта

Независимо от того,

вручную

когда и

вам

DataAdapter

необходимо

выполнить

1. Убедитесь, что объект connection создан и расположен на проектируе- мой форме или компоненте.

2. Из вкладки Data окна Toolbox перенесите объект OleDbDataAdapter или SqlDataAdapter в область дизайнера формы. Visual Studio добавит соот- ветствующий объект DataAdapter к форме и запустит мастер Data Adapter Configuration

3. Закройте мастера Data Adapter Configuration Wizard.

ADO.NET пак базовый объект доступа к базам данных

57

Процесс

следующем.

ручного

конфигурирования

объекта

DataAdapter

заключается

в

1. Выделите мышью объект DataAdapter и перейдите в окно Properties, где можно сформировать команды, позволяющие читать и обновлять данные. В первую очередь необходимо сформировать объект

SelectCommand (рис. 1.25). Если DataAdapter будет использоваться И

источника

необходимо

для

модернизации

таблицы

данных,

то

также

Сформировать объекты UpdateCommand, DeleteCommand, InsertCommand.

Рис. 1.25. Ручное формирование свойств команды SelectCommand в окне Properties адаптера данных

Для

каждого объекта Command

(табл. 1.2).

Свойство

Описание

необходимо задать следующие свойства

Таблица 1.2, Свойства объекта Command

ActiveConnection Устанавливает ссылку на объект Connection. Кроме того, мож- но создать новый объект Connection в свойстве ActiveConnection окна Properties. Как правило, все объекты Command используют один и тот же объект Connection. Однако вы имеете возможность использования различных объектов Connection для каждого из объектов Command

CommandText Содержит текст SQL-запроса или имя хранимой процедуры. Для некоторых провайдеров возможно создание мультизапроса или хранимой процедуры с несколькими инструкциями, разделен- ными точкой с запятой (;). Эти инструкции выполняются после- довательно. Это полезно для ситуаций, когда после добавления или удаления записей нужно повторно получить из базы данных обновленную информацию

58_

Глава 1

Таблица 1.2. (окончание)

Свойство

Описание

CommandType

Тип команды в свойстве CommandText. дующее значения:

Может принимать сле-

O Text — текст SQL-запроса

O StoredProcedure — хранимая

О TableDirect - ИМЯ Таблицы

процедура

Parameters Коллекция объектов Parameter , через которые значения пара- метров передаются команде. 8 объекте SelectCommand соз- дается коллекция параметров только в том случае, если коман- да возвращает не все записи исходной таблицы. Объекты UpdateCommand, InsertCommand И DeleteCommand всегда требуют определения параметров

2. Определите свойство MissingMappingAction. По умолчанию это свойство имеет значение Passthrough, при котором именам таблиц и колонок ре- зультирующего набора данных автоматически присваиваются имена со- ответствующих элементов источника данных. Если вы не хотите иметь одинаковые имена столбцов в таблице источника данных и таблице на- бора данных нужно задать желаемую схему соответствия данных.

3. В меню Data выберите пункт Generate DataSet.

Если отсутствует меню Data, то нужно щелкнуть мышью в любом месте формы, этот пункт доступен только тогда, когда фокус установлен в окне дизайнера формы.

4. Если вы хотите увидеть, какими данными DataAdapter заполнил набор данных DataSet, вызовите окно предварительного просмотра данных.

1.4.7. Конфигурирование параметров объекта DataAdapter

В большинстве случаев команды адаптера данных (SelectCommand, InsertCommand, UpdateCommand И DeleteCommand) построены на основе SQL- запросов с параметрами. Если для создания объекта DataAdapter использо- вать мастер Data Adapter Configuration Wizard, то параметры для этих команд будут сконфигурированы автоматически. Однако вы можете сконфигуриро- вать параметры вручную, или сделать необходимые изменения в уже суще- ствующей коллекции параметров.

ADO.NET как базовый объект доступа к базам данных

59

Для конфигурирования параметров после изменения текста SQL-запроса объ- екта Command необходимо установить флажок Regenerate parameters collection for this command в построителе запросов Query Builder.

Для конфигурации параметров объекта DataAdapter необходимо.

1. Создать объект DataAdapter.

2,

В форме мышью выделить объект DataAdapter

Properties (рис.

1.26).

и открыть окно свойств

Рис. 1.26. Доступ к коллекции параметров команды UpdateCommand в окне свойств объекта SqlDataAdapter

3. Раскройте объект Command, для которого вы хотите сконфигурировать параметры (например, UpdateCommand) и затем в свойстве Parameters нажмите кнопку, чтобы открыть окно SqlParameter Collection Editor (рис. 1.27).

Рис.

1,27. Окно конфигурирования параметров команды UpdateCommand

60

Глава 1

4. Для создания нового параметра щелкните на кнопке Add.

5. Переместите новый параметр в нужное место коллекции, используя кнопки со стрелками для перемещения его вверх или вниз.

6. Чтобы установить требуемое свойства параметра, выберите его в списке Members и затем назначьте ему нужное свойство. В табл. 1.3. перечис- лены типовые свойства, которые вы можете установить.

Таблица 1.3. Свойства параметров объектов DataCommand адаптера данных

Свойство

Описание

SourceColumn Имя столбца в таблице набора данных, из которого будет читаться значение параметра. Это свойство используется с параметрами, которые заполняются значениями в запросах UPDATE, INSERT или DELETE (то же в хранимых процедурах)

SourceVersion

Если параметр получает значение из свойства SourceColumn, то SourceVersion определяет, какая версия записи набора данных будет использоваться, как источник значения параметра;

O Original — значение столбца, которое было получено из базы данных. Вы можете использовать данное значение тогда, ко- гда вам необходимо иметь то значение столбца, которое бы- ло до его изменения. Например, было изменено значение ключевого поля, но вам необходимо иметь старое значение этого поля, чтобы найти нужную запись в базе данных

O Current — значение столбца после того, как запись была изменена. Это обычно то значение, которое будет записано в базу данных

O Default

значение,

которое

будет

присвоено

столбцу,

если

никакое другое значение явно не задано

 

Value

Значение, присвоенное параметру. Это свойство обычно устанав- ливается динамически (во время выполнения программы), а не статически во время ее разработки

Свойство Value имеет приоритет по отношению к свойству SourceColumn, если они оба установлены

NamedParameter Поименованный параметр. Булево значение, указывающее, что параметр является переменной с именем (@parametername) или меткой (?). Если вы работаете с объектом SqlConnection и ис- пользуете поименованные параметры, то установите значение NamedParameter равным true

DBType, Preci- Информация о типе значения параметра (в источнике данных), sion, Scale, Значение параметра будет конвертировано в тип данных, который Size вы определили, или из него

ADO.NET как базовый объект доступа к базам данных

61

Таблица 1.3. (окончание)

Свойство

Описание

Direction

Указание направления: передается ли значение параметра к ко- манде или от команды:

• Input — значение

передается

к

команде.

Это значение

установлено по умолчанию

• Output — значение передается к хранимой процедуре (не используется с SQL-запросами)

• InputOutput

— значение передаются к хранимым про-

цедурам

и

возвращаются

назад,

обычно

в

измененном

виде

• ReturnValue — явно возвращаемое значение.

По умол-

чанию возвращаемое значение — первый элемент в кол- лекции параметров (с индексом 0)

ParameterName Имя, по которому можно обратиться к параметру вместо его но- мера в коллекции. Для простоты последующего сопровождения приложения рекомендуется использовать имя параметра, а не его номер

1.

Нажмите кнопку ОК для закрытия окна SqlParameter Collection Editor.

8.

Повторите

шаги

с

3-го по

7-й

для

задания

конфигурации

параметров

ДРУГИХОбъектовCommand.

1.4.8. Связывание колонок таблиц источника данных и объекта DataSet через адаптер данных

В Visual Studio в объекте DataAdapter имеется возможность установить со- ответствие между колонками таблицы базы данных (источника данных) и колонками таблицы объекта DataSet. Это обеспечивает возможность сме- нить наименование колонок и сделать их удобочитаемыми как для разра- ботчика, так и для конечного пользователя приложения.

Для

дующие действия.

сле-

установления

соответствия

между

колонками таблиц

выполните

1. Создайте объект DataAdapter.

2. Мышью установите фокус на объекте DataAdapter в окне дизайнера формы и откройте окно Properties этого объекта.