До появления объектов ADO при работе с базой данных Access использовались объекты DAO (Data Access Objects), являющиеся предшественниками ADO. Они и сейчас, естественно, могут использоваться в уже разработанных и действующих приложениях. В новых разработках следует отдать предпочтение объектам ADO. Объектные модели ADO и DAO хотя и имеют много общего, но имеют и существенные различия. Так что вряд ли целесообразно переходить к новым объектам в уже работающих приложениях, если это не вызвано особыми причинами. В этом разделе я приведу сравнение объектных моделей и другие сведения, облегчающие переход от DAO к ADO в случае, если такая необходимость возникла.
В объектной модели DAO есть корневой объект - DBEngine, определяющий машину баз данных. В этот объект вложена коллекция объектов Workspaces, каждый элемент которой - объект Workspace - задает сеанс работы, являясь неким эквивалентом объекта Session в модели OLE DB. В модели ADO сеанс работы связывается с объектом Connection, задающим соединение с базой данных. Заметьте, модель ADO во многом упрощена в сравнении с моделью DAO, - в ней нет даже такого объекта как объект Database, являющегося одним из основных объектов в модели DAO.
Конечно, главное достижение в модели ADO связано с возможностью работы с разнообразными источниками данных и введением такого понятия как Провайдер. В модели DAO, в которой можно работать только с двумя Провайдерами, отсутствие этого понятия и универсального подхода, характерного для ADO, привело к существенному осложнению самой модели. Модель DAO позволяет в течение одной сессии, или, другими словами, в рабочем пространстве работать либо с источником данных Microsoft Jet, либо с ODBC - источниками данных. С объектной точки зрения это означает, что в объект WorkSpace, задающий рабочее пространство, вкладываются две достаточно разные совокупности объектов. Я ограничусь рассмотрением лишь одной половинки этой модели и рассмотрю модель DAO, связанную с источниками данных Microsoft Jet. Взгляните, как выглядит объектная модель DAO для этого случая:
Обратите внимание, чтобы не усложнять схему, на нижних уровнях иерархии ряд объектов опущен. Вот как следует дополнить эту схему:
Я уже говорил, что объектная модель DAO намного сложнее, чем модель ADO. Чтобы в полной мере реализовать функциональность, обеспечиваемую объектами DAO, представленными на рис. 6.6, в модели АДО потребуется использовать три группы объектов и, соответственно, подключить три различные библиотеки объектов:
Я не буду останавливаться на деталях сходства и различия в моделях ADO и DAO. Отмечу еще только два момента:
Объекты этой группы, как уже было сказано, играют важную роль, позволяя работать с метаданными баз данных. С их помощью можно программно создать новую базу данных, создать или модифицировать элементы существующей базы данных, создать новые или модифицировать существующие таблицы, запросы, хранимые процедуры. Кроме того, эти объекты предназначены для работы с пользователями, группами пользователей, задания их прав доступа к данным, обеспечивая, тем самым, нужный уровень безопасности.
Рассмотрим объектную модель ADOX и начнем со схемы, отражающей взаимосвязи между объектами модели:
На схеме не отражен тот факт, что объекты Table, Index, Column имеют стандартную коллекцию Properties с элементами Property.
Заметьте, в этой модели есть центральный объект Catalog, в который и встроены все основные коллекции: Tables, Procedures, Views, Groups, Users. Эти коллекции определяют различные метаэлементы базы данных. Давайте подробно рассмотрим свойства и методы объектов модели.
Центральный объект модели ADOX, задает каталог базы данных. Его метод Create позволяет создать новый источник данных, а свойства позволяют добраться до элементов, определяющих схему базы данных. Не все Провайдеры поддерживают полный набор возможностей этого объекта, определяемых его свойствами и методами. Так что источник данных и его Провайдер определяют, допустимо ли для него использование того или иного свойства или метода объектов ADOX.
У объекта Catalog 6 свойств: ActiveConnection, Tables, Procedures, Views, Groups, Users. Пять последних свойств возвращают одноименные коллекции. А о первом свойстве поговорим чуть подробнее.
Свойство имеет статус "чтение/запись". Синтаксически определяется следующим образом:
Property ActiveConnection As Variant
Позволяет установить ссылку на объект Connection или задать строку, определяющую соединение. Возвращает ссылку на активный объект Connection.
С объектной точки зрения все эти коллекции устроены одинаково. Они хранят соответствующие элементы классов: Table, Procedure, View, Group, User. У них есть три метода и два свойства. Для добавления нового элемента в коллекцию применяется метод Append(item), удаления - метод Delete(item), для обновления состояния коллекции, учитывающего текущее состояние базы данных - метод Refresh(). Свойство Item позволяет добраться до нужного элемента коллекции, а свойство Count возвращает число элементов в коллекции.
Некоторая особенность связана с коллекциями Groups и Users. Коллекция Groups объекта Catalog задает все группы базы данных. С другой стороны, как показано на схеме, отражающей связи между объектами (Рис. 7), коллекция Groups связана и с отдельным объектом User. Коллекция групп, связанная с отдельным пользователем, возвращает все группы, в которые входит этот пользователь. Заметьте, прежде чем добавить новую группу с именем name в коллекцию Groups объекта User, элемент с таким именем уже должен находиться в коллекции Groups объекта Catalog. Совершенно симметрично дело обстоит и с коллекцией Users, которая в объекте Catalog описывает всех пользователей, а в объекте Group - пользователей данной группы. Аналогично, прежде чем добавить пользователя в отдельную группу, он должен быть добавлен в коллекцию Users объекта Catalog .
У этого объекта три метода:
Эти два метода позволяют определить и, соответственно, установить собственника объекта. Параметр UserName метода Set задает имя собственника, которое возвращает метод (функция) Get. Параметры ObjectName и ObjectType задают имя и тип объекта, для которого устанавливается собственник. Наличие этих параметров связано с тем, что методы применимы не только к объекту Catalog. Тип объекта задается константами из перечисления ObjectTypeEnum. Вот их значения: adPermObjColumn, adPermObjDatabase, adPermObjProcedure, adPermObjTable, adPermObjView. Еще одно возможное значение - adPermObjProviderSpecific указывается тогда, когда объект не принадлежит ни к одному из указанных типов и зависит от Провайдера, в этой ситуации тип задается последним параметром ObjectTypeId.
Чтобы оживить изложение, давайте перейдем к рассмотрению примеров. Для экспериментов с объектами ADOX я создал новый модуль. Глобальные переменные этого модуля будут определять уже знакомые объекты - Connection, Command, Recordset. Но к ним теперь добавится и новый объект, задающий Catalog.
Option Explicit 'Модуль TestingADOX 'Глобальные переменные Public Con1 As New ADODB.Connection Public Cmd1 As New ADODB.Command Public Rst1 As New ADODB.Recordset Public Strm1 As New ADODB.Stream Public Cat1 As New ADOX.Catalog
Вот как выглядит первая процедура этого модуля, создающая новую базу данных:
Public Sub CreateNewDB() 'Создание новой базы данных и открытие соединения с ней Dim strConnStr As String strConnStr = "Provider=Microsoft.jet.oledb.4.0;" & _ "Data Source=c:\!O2000\DsCd\Ch16\NewDB.mdb" Set Con1 = Cat1.Create(strConnStr) Debug.Print Cat1.ActiveConnection Dim Con2 As Connection Set Con2 = Cat1.ActiveConnection Debug.Print Con2.ConnectionString End Sub
В этой процедуре я создал новую базу данных Access и установил с ней соединение. Заметьте, я ввел два объекта класса Connection, - один из них определяется при вызове метода Create объекта Cat1 класса Catalog, а второй определяется, используя значение свойства ActiveConnection. Отладочная печать в обоих случаях одинакова и дает следующий результат:
Provider=Microsoft.Jet.OLEDB.4.0;Password="";User ID=Admin;Data Source=c:\!O2000\DsCd\Ch16\NewDB.mdb;Mode=Share Deny None;Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry Path="";Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False
В ней отражены все свойства объекта Connection.