От автора

Сложилось так, что этой статье суждено увидеть свет задолго до запланированного мной срока. Я намеревался продвигаться поэтапно: рассказать об истории и причинах появления СУБД, доступно изложить основные положения теории реляционных баз данных, рассказать о реализациях СУБД (на примере продуктов от Microsoft, с которыми я работаю большую часть времени) и лишь затем приступить к изложению темы о технологиях и средствах доступа к реляционным базам данных. Причем опять же ADO.NET должна была скромно дожидаться своей очереди после ODBC, DAO, OLE DB и ADO (в хронологическом порядке их появления).

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

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

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

Alf


Архитектура ADO.NET


Что такое ADO.NET


Коротко на этот вопрос можно ответить так: это основная технология доступа к данным (строго говоря, не только реляционным, хотя в своем цикле я рассматриваю только реляционные базы данных) для платформы .NET. Более конкретно это набор объектов, при помощи которых программист может осуществить подключение к серверу баз данных, выборку данных и/или их модификацию.

MSDN определяет аббревиатуру ADO.NET как ActiveX Data Objects for the .NET Framework. Внимательный читатель сразу же заметит подвох. Что, собственно, делает в среде .NET, которая, как известно, объявила о своей автономии от COM, технология, базирующаяся на ActiveX?

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

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

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

Для чего разработана ADO.NET


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

ADO была разработана для архитектуры клиент-сервер. Эта архитектура в течение ряда лет была достаточно прогрессивной, если учесть, что пришла она на смену архитектуре файл-сервер. Потом все нарастающая сложность систем обработки данных потребовала качественного изменения архитектуры: кроме двух уровней клиент и сервер баз данных появляются дополнительные уровни серверы, реализующие бизнес-логику приложений. До сих пор, правда, ни одна из разработанных для этой цели архитектур (в частности, DCOM и CORBA) не добились впечатляющих успехов в этом направлении, и на сегодняшний момент мне известно, пожалуй, больше вирусов, использующих их слабости, чем реально работающих продуктов на их основе. .NET в целом и ADO.NET в частности очередная попытка навести порядок в сегменте многоуровневых приложений и сделать их разработку относительно простым и приятным занятием. Что из этого выйдет, судить пока рано, но, на мой взгляд, перспективы неплохи.

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

Искушенные в ADO программисты могут возразить, что, мол, мы уже давно имели такую возможность в виде отсоединенных наборов записей. Да, частично они правы. Однако отсоединенные наборы записей стоят несколько особняком в объектной модели ADO, и их функциональность оставляет желать лучшего.

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

Объектная модель ADO.NET

MSDN изображает объеектную модель ADO.NET следующим образом:



Как видно из данной диаграммы, основу ADO.NET составляют два основных компонента (разумеется, в данном случае речь не идет о компонентах COM): DataSet и Провайдер Данных.

Провайдер данных

Провайдер Данных, как это ясно следует из его названия, отвечает за связь приложения с источником данных и манипуляции данными. Основные объекты, входящие в его состав, - это Connection, Command, DataAdapter иDataReader.

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

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

DataAdapter служит связующим звеном между DataSet и источником данных. Он использует Command для выполнения команд SQL как для заполнения DataSet данными, так и для обратной передачи измененных клиентом данных к источнику. Для выполнения этих функций объект имеет 4 метода: SelectCommand, InsertCommand, UpdateCommand и Deletecommand.

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

DataSet

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

ataSet может сохранять свое текущее содержимое в файлах XML, а схему в виде XML Schema definition language (XSD).

Внутреннее устройство DataSet (заимствовано из MSDN):



Рассмотрим вкратце наиболее важные компоненты DataSet, не углубляясь во второстепенные детали.

DataSet включает две основные коллекции: DataTableCollection и DataRelationCollection.

DataTableCollection это коллекция объектов DataTable, каждый из которых представляет одну таблицу отношения и в свою очередь состоит из коллекций:

* DataColumnCollection представляет все столбцы таблицы. Помимо данных, столбец может включать формулу для динамического расчета своего содержимого.
* DataRowCollection представляет набор строк таблицы (возможно, пустой). Следует отметить, что хранятся не только текущие значения данных, но и первоначальные, что позволяет выделить измененные данные.
* ConstraintCollection набор ограничений целостности данных (например, можно задать, допустимо ли для данного столбца значение NULL или должны ли данные быть уникальными).


Другая коллекция из состава DataSet это DataRelationCollection, которая служит для навигации по связанному набору таблиц и содержит ограничения ссылочной целостности DataSet. В ней, например, можно задать ограничения, которое не позволит удалить запись главной таблицы, если на нее есть ссылки в подчиненной таблице посредством внешнего ключа, тем самым не допуская появления осиротевших (orphaned) записей.

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

Провайдеры Данных


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

Совместно с платформой .NET поставляется два штатных Провайдера: SQL Server .NET Data Provider и OLE DB .NET Data Provider. С Web-узла Microsoft можно загрузить ODBC .NET Data Provider (естественно, для работы с источниками данных ODBC). Ходят слухи о скором выпуске специального Провайдера для Oracle.

SQL Server .NET Data Provider оптимизирован для работы с Microsoft SQL Server V7.0 и выше. Он потребляет меньше ресурсов, чем Провайдер OLE DB, и обладает лучшей производительностью. За это приходится платить потерей переносимости на другие сервера баз данных. Находится этот Провайдер в пространстве имен System.Data.SqlClient.

OLE DB .NET Data Provider это более общий Провайдер, способный работать с почти любым источником данных, поддерживающим OLE DB (исключения представлены делее). Разумеется, для своей работы он использует COM, поэтому между Провайдером и источником данных в этом случае присутствуют две прослойки: обертка, позволяющая managed-приложению использовать COM, и собственно провайдер OLE DB для COM. Естественно, в этом случае производительность уступает предыдущему решению, зато можно использовать практически любые источники данных. Находится этот провайдер в пространстве имен System.Data.OleDb.

Microsoft тестировал ADO.NET со следующими провайдерами OLE DB:
Driver Provider
SQLOLEDB Microsoft OLE DB Provider for SQL Server
MSDAORA Microsoft OLE DB Provider for Oracle
Microsoft.Jet.OLEDB.4.0 OLE DB Provider for Microsoft Jet
Не поддерживается OLE DB Provider for ODBC (MSDASQL), а также OLE DB version 2.5 (в частности, Microsoft OLE DB Provider for Exchange и the Microsoft OLE DB Provider for Internet Publishing). Не рекомендуется использование баз данных Microsoft Access для многоуровневых приложений.

Для корректной работы Провайдера OLE DB следует установить MDAC 2.6 и выше.

Следует заметить, что хотя все Провайдеры предназначены для одной цели, тем не менее между ними есть разница в деталях строения. Поэтому перейти, допустим, с MS SQL на Oracle простым переименованием объекта не получится, придется внести некоторые изменения в текст программы. Эти изменения не столь обширны, но все же нужно иметь их в виду.

Простой пример приложения ADO.NET


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

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

Итак, вот текст программы на языке C#. Для простоты она оформлена в виде консольного приложения. Создайте в среде Visual Studio .NET пустой проект консольного приложения, скопируйте в него текст программы и все должно заработать. Конечно же, те, кто пока обходится без Visual Studio и пользуется .NET Framework, тоже могут откомпилировать ее из командной строки. Я бы рекомендовал выполнить ее по шагам в отладчике и понаблюдать за изменениями состояния объектов программы.
Код:
using System;
using System.Data;
using System.Data.OleDb;
namespace ConsoleApplication1
{
class CAdoNetSample
{
[STAThread]
static void Main(string[] args)
{
// строка соединения; настройте ее на расположение базы
//данных Борей.mdb в вашей системе
string strConn=
"Provider=Microsoft.Jet.OLEDB.4.0;Password="";User ID=Admin;"+
"Data Source=C:\Program Files\Microsoft Office\Office10\Samples\Борей.mdb;";

// создаем Connection и открываем его
OleDbConnection cnn = new OleDbConnection(strConn);
cnn.Open();

// создаем команду SQL, которая выберет все страны, в которых
// живут клиенты, и упорядочит их список по алфавиту обратите
// внимание - создаваемая команда связана с соединением cnn
OleDbCommand cmd = cnn.CreateCommand();
cmd.CommandText=
"SELECT DISTINCT Страна FROM Клиенты ORDER BY Страна";

// поскольку мы намереваемся читать список последовательно,
// то нас вполне устроит функциональность объекта DataReader
// выполняем команду; результаты ее выполнения будут доступны
// через rdr
OleDbDataReader rdr = cmd.ExecuteReader();

// выдаем на печать все полученные результаты
while (rdr.Read())
{
Console.WriteLine(rdr.GetString(0));
}

// освобождаем занятые ресурсы
rdr.Close();
cnn.Close();
}
}
}
(Продолжение следует).


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

Автор: Alf
Information
  • Posted on 31.01.2010 21:48
  • Просмотры: 536