Главная Рефераты по геополитике Рефераты по государству и праву Рефераты по гражданскому праву и процессу Рефераты по делопроизводству Рефераты по кредитованию Рефераты по естествознанию Рефераты по истории техники Рефераты по журналистике Рефераты по зоологии Рефераты по инвестициям Рефераты по информатике Исторические личности Рефераты по кибернетике Рефераты по коммуникации и связи Рефераты по косметологии Рефераты по криминалистике Рефераты по криминологии Рефераты по науке и технике Рефераты по кулинарии Рефераты по культурологии Рефераты по зарубежной литературе Рефераты по логике Рефераты по логистике Рефераты по маркетингу Рефераты по международному публичному праву Рефераты по международному частному праву Рефераты по международным отношениям Рефераты по культуре и искусству Рефераты по менеджменту Рефераты по металлургии Рефераты по муниципальному праву Рефераты по налогообложению Рефераты по оккультизму и уфологии Рефераты по педагогике Рефераты по политологии Рефераты по праву Биографии Рефераты по предпринимательству Рефераты по психологии Рефераты по радиоэлектронике Рефераты по риторике Рефераты по социологии Рефераты по статистике Рефераты по страхованию Рефераты по строительству Рефераты по схемотехнике Рефераты по таможенной системе Сочинения по литературе и русскому языку Рефераты по теории государства и права Рефераты по теории организации Рефераты по теплотехнике Рефераты по технологии Рефераты по товароведению Рефераты по транспорту Рефераты по трудовому праву Рефераты по туризму Рефераты по уголовному праву и процессу Рефераты по управлению |
Реферат: Введение в ObjectSpacesРеферат: Введение в ObjectSpacesТимофей Казаков (TK) Сохраняемые объектыВ .NET Framework управление данными осуществляется на уровне объектов. Каждый объект характеризуется своим состоянием (свойства), поведением (методы), и является экземпляром какого-либо конкретного класса. В рамках приложения классы могут различаться по целевому назначению – это могут быть элементы управления, отображающие интерфейс пользователя, или сервисные классы, отвечающие за связи с базами данных и работу с сетевыми функциями, это могут быть классы “сообщений”, обеспечивающие обмен информацией между частями приложения. Все эти сущности объединяет одна общая черта – время их жизни обычно не превышает времени жизни всего приложения. Но, кроме вышеперечисленных категорий классов, можно выделить целый ряд сущностей, время жизни которых превышает срок жизни приложения. Например, в бизнес-задачах роль подобных сущностей могут играть объекты “Клиент”, “Заказчик”, “Продукт”. Таким объектам необходимо предоставить возможность сохранения своего состояния во внешнее хранилище. В .NET Framework существуют готовые средства для работы с сохраняемыми объектами, – есть возможность сохранять состояние объектов в двоичном виде с использованием BinaryFormatter или XML-формате с использованием XmlSerializer. Все эти средства предоставляют возможности сохранения “графов” объектов, однако сохраняемая информация не оптимизирована для выполнения запросов к хранимым данным – так, поиск необходимой информации в XML-файле, содержащем несколько тысяч записей, может оказаться неприемлемо медленным. В большинстве подобных случаев в качестве хранилища информации подойдет реляционная СУБД – данные сохраняются в таблицах, для дополнительного контроля целостности между ними устанавливаются отношения, поиск информации осуществляется с использованием языка запросов SQL. Аналогичную функциональность предоставляют специальные библиотеки Object/Relational Mapping (O/R Mapping). Такая библиотека перекладывает на себя всю “черную” работу по сохранению/загрузке информации из объектной модели приложения в реляционную модель базы данных. В .NET Framework 1.2 для этих целей есть специальный набор классов из пространства имен System.ObjectSpaces.*. ObjectSpacesЕсли раньше, используя ADO.NET, нужно было самостоятельно писать SQL-запросы, то теперь это требование становится необязательным – ObjectSpaces берут на себя всю заботу об отображении классов приложения на различные источники данных. При этом мы можем создавать новые объекты, сохранять их, выполнять различные запросы - все необходимые действия по взаимодействию с источником данных будут выполняться внутри ObjectSpaces (при этом данные могут находиться как в традиционной БД, так и быть представленными в XML форме)
Для объектов приложения ObjectSpaces предоставляет следующие возможности: Прозрачное отображение экземпляров .NET объектов на источник данных. Поддержку иерархий классов для сохраняемых объектов. Сохранение взаимосвязей между объектами (один к одному, один ко многим, многие ко многим). Отложенную загрузку связанных объектов. Построение запросов с использованием OPath. Архитектура ObjectSpacesКакая функциональность требуется от O/R Mapping-библиотеки? Кроме очевидных задач – загрузки/сохранения состояния объекта и выполнения операций поиска, есть и менее очевидные задачи – отслеживание состояния и идентификация объекта. Для чего это нужно? Отслеживание состояния требуется для принятия решения о необходимости сохранения объекта. Совершенно очевидно, что если ни одно из полей объекта не изменялось, то повторно сохранять ту же информацию совершенно не обязательно. Информация об оригинальных значениях полей может понадобиться и для достижения “оптимистической параллельности” (optimistic concurrency) в ситуациях, когда в БД нет колонки с версией записи. Также можно оптимизировать сохранение полей объекта для ситуаций, когда один объект отображается на несколько таблиц в базе данных, просто не обновляя не изменившиеся данные.
В каких случаях нужно уметь идентифицировать объект? В случае с O/R Mapping-библиотекой мы работаем не с “сырыми” данными, а с реальными объектами. Это значит, что одному значению первичного ключа в базе данных должен соответствовать один объект в приложении. В самом деле, разумно рассчитывать, что все возможные способы получения одного и того же объекта из базы данных каждый раз должны возвращать одну и ту же ссылку. Это означает, что O/R Mapping-библиотека должна отслеживать все загружаемые объекты, и в случае повторной попытки восстановить объект с тем же значением первичного ключа возвращать ссылку на уже загруженный. Какие есть пути для реализации подобной функциональности? Реализация функциональности идентификации объектов пересекается с реализацией отслеживания состояния объекта и не представляет особой сложности. Поэтому сосредоточимся на том, какими способами можно обеспечить отслеживание состояния. Есть два варианта отслеживания состояния объекта. В первом варианте инициатором сохранения состояния выступает сам объект. По второму варианту объект играет пассивную роль, а вся необходимая функциональность реализуется в библиотеке O/R Mapper. Разберем каждую из двух реализаций более подробно. Инициатором сохранения выступает объект. В данной ситуации O/R Mapper предоставляет механизм хранения оригинальных и текущих значений, а “сохраняемый” объект выступает лишь интерфейсом для работы c этим хранилищем. Здесь можно выделить два возможных направления: “Сохраняемый” класс описывается на некотором метаязыке. Что это за метаязык, и какие средства работы с ним используются, в общем случае не столь важно. Отличительной особенностью данной реализации является то, что весь необходимый код отслеживания состояния генерируется на этапе разработки (компиляции). В качестве примера подобного подхода можно взять реализацию Borland Enterprise Core Objects (ECO). Все свойства, для которых необходимо предоставить возможности “сохранения” объявляются как абстрактные, сам такой класс также становится абстрактным (MustInherit в VisualBasic). На O/R Mapping-библиотеку в такой ситуации ложится ответственность за создание наследника “сохраняемого” (например, через Reflection.Emit) класса с неизбежной реализацией всех сохраняемых свойств, и предоставление фабрики класса для его создания. Найти реализацию подобной функциональности можно в ранней preview-версии ObjectSpaces и в EntityBroker (http://www.thona-consulting.com). У каждого из этих направлений есть свои достоинства и недостатки. Плюсом первого направления является более быстрый запуск, т.к. весь необходимый код сгенерирован еще на этапе компиляции. Между тем, этот плюс может стать и минусом – если по какой-то причине реализация “отслеживания” состояния изменится, придется повторить операцию генерации кода сохраняемого класса и перекомпилировать его. В случае использования второго направления будет достаточно заменить реализацию O/R Mapper. Объект играет пассивную роль, вся реализация – в O/R Mapper. В этой ситуации к “сохраняемому” классу не предъявляется никаких дополнительных требований. Основной плюс данного подхода состоит в том, что для добавления “сохраняемости” к существующему классу его не надо никак модифицировать (максимальная прозрачность в использовании O/R Mapper), а минус состоит в том, что для сохранения закрытых полей класса приходится использовать механизмы рефлексии, что может отрицательно сказаться на производительности. В ObjectSpaces выбран второй вариант. В основе реализации ObjectSpaces (Рисунок 1) лежат три основных класса: ObjectEngine, ObjectContext и ObjectSpace. ObjectEngine (его использование более подробно рассматривается ниже) отвечает за низкоуровневое взаимодействие с источником данных. ObjectContext – это реализация механизмов идентификации и отслеживания состояния “сохраняемых” классов. ObjectSpace. Класс ObjectSpace на более высоком уровне объединяет функциональность, заложенную в реализациях ObjectEngine и ObjectContext. Для отображения реляционной модели данных в объектную ObjectSpace использует набор XML-схем, описываемых классом MappingSchema. Рисунок 1 Архитектура ObjectSpaces. Схемы данных Для большинства приложений описать однозначное (“один к одному”) отображение объектной модели данных на реляционную модель нельзя, иногда нужно специально описывать то, как объекты должны отображаться на источник данных. В ObjectSpaces эту задачу выполняет класс MappingSchema (пространство имен System.Data.Mapping). Данный класс предназначен для описания: RSD (Relational Schema Definition) – схемы, которая описывает таблицы, поля и отношения между ними; OSD (Object Schema Definition) – схемы, описывающей объекты; MSD (Mapping Schema Definition) – схемы отображения. ObjectSpaces дает возможность самостоятельно формировать состояние класса MappingSchema или загружать его состояние из XML-файла. Рассмотрим использование MappingSchema на основе базы данных Northwind из состава SQL Server. На первом этапе нужно описать структуру этой базы данных в RSD-схеме:
Эта схема описывает две таблицы из базы данных Northwind (рисунок 2). Для таблиц Customers и Orders описываются исходные поля в БД, первичные ключи, а также связи между таблицами. Рисунок 2. ER-диаграмма Кроме этого, понадобится описать OSD-схему, которая будет описывать объекты C#-кода.
Рисунок 3. Объектная модель. После объявления RSD- и OSD-схем (рисунок 3), нужно создать Mapping-схему, которая определит отображение одной схемы на другую:
OPath Одна из основных задач при работе с информацией – это создание запросов для выборки необходимых данных. Так, в случае РСУБД можно использовать язык запросов SQL, для выборки информации из XML-источников у нас есть XPath. Но как SQL, так и XPath – это языки запросов, которые слишком сильно привязаны к модели хранения данных и, как результат, для O/R Mapper приходится применять специальный язык запросов, который позволит создавать запросы к данным в терминах объектной модели приложения и легко транслировать их в язык, понимаемый хранилищем данных (для ObjectSpaces и MS SQL Server это SQL). Для обращения к источнику данных в ObjectSpaces используется специальный язык запросов – OPath. Синтаксис этого языка (отдаленно он напоминает XPath) позволяет выполнять запросы к источнику данных, основываясь на иерархии классов, используемых в приложении. В настоящее время OPath поддерживает следующий набор операторов (для операторов может использоваться синтаксис как C#, так и VB.NET):
ObjectSpace При работе с сохраняемыми объектами нам нужны следующие возможности – загрузка сохраненных объектов, отслеживание состояния и возврат изменений обратно, в базу данных. Класс ObjectSpace объединяет в себе все эти возможности. Рассмотрим отдельные моменты работы с этим классом. Создание экземпляра ObjectSpace Для создания экземпляра ObjectSpace нужно иметь три схемы – RSD, OSD и MSD (при желании их можно скомбинировать в одном XML-файле), а также экземпляр SqlConnection для взаимодействия с источником данных.
Запрос к источнику данных После инициализации экземпляра ObjectSpace можно обратиться к источнику данных. Для этого у класса ObjectSpace есть три метода GetObject, GetObjectReader, GetObjectSet которые позволяют получать данные в виде трех различных форм – одиночный объект, курсор или список.
Во что выливается вызов приведенного выше метода os.GetObject? Используя Profiler из MS SQL Server, можно увидеть, что в БД будет выполнен следующий SQL-запрос (отформатирован для приведения в более “читаемый” вид):
Создание записей в базе данных Одно из больших преимуществ в использовании ObjectSpaces состоит в том, что для добавления объекту свойств “сохраняемости” его не надо специальным образом модифицировать (наследовать от специального базового класса, специальным образом размечать свойства или поля). Подобная прозрачность реализации ObjectSpaces дает преимущества в использовании.
Удаление записей с использованием ObjectSpaces Существующая версия ObjectSpaces поддерживает удаление объектов только в том случае, если они ранее были добавлены в контекст ObjectSpaces.
Отложенная загрузка данных Отложенная загрузка данных – это очень полезная возможность, реализованная в ObjectSpaces. Правда, использование этой функциональности омрачается ее недостаточной “прозрачностью”. Это значит, что в случае, когда необходимо подгружать зависимые классы по требованию, придется модифицировать исходный код. К счастью, модификации незначительны.
Кроме изменения кода приложения, отложенную загрузку свойств следует объявить в OSD-схеме. Для этого нужно добавить в описание полей специальный атрибут LazyLoad=”true”.
После этого можно работать с восстановленным объектом как обычно:
Дополнительные возможности ObjectSpaces Чтение данных с использованием DbObjectReader В отдельных случаях использование класса ObjectSpace может оказаться избыточным или неудобным. Например, если для доступа к базе данных необходимо использовать хранимые процедуры, большая часть функциональности ObjectSpaces окажется ненужной. Но и для подобных ситуаций в ObjectSpaces есть свое решение. Если требуется извлекать из произвольного источника данных информацию в виде объектов приложения, можно использовать класс DbObjectReader. Выступая как тонкая прослойка между ADO.NET-курсором (IDataReader) и классами приложения, DbObjectReader позволяет загружать сохраняемые объекты из источников данных, которые не поддерживаются ObjectSpaces напрямую.
ObjectEngine Класс ObjectEngine лежит в основе ObjectSpaces и реализует механизмы взаимодействия с источником данных. В большинстве случаев ObjectEngine напрямую не используется, но в ситуациях, когда необходимо выполнить OPath-запрос или сохранить объект в БД в обход основной функциональности ObjectSpaces и с минимальными издержками – использование ObjectEngine может пригодиться.
Расширения ObjectSpaces Использование нескольких XML-схем для описания структуры классов приложения, реляционной структуры БД, а кроме того еще и Mapping-схемы, не может не удручать. Конечно, в финальной версии .NET Framework 1.2 возможности визуального проектирования этих схем должны обязательно появиться, но пока их нет, можно воспользоваться сторонними средствами. Одно из таких средств входит в пример ObjectSpacesPDCSamples.zip (файл можно найти на http://www.gotdotnet.com). В состав этого примера входит специальная утилита для создания всех необходимых XML-схем (рисунок 4). Рисунок 4. Microsoft ObjectSpaces Mapper Utility. Кроме этого, в данный пример входит реализация класса ObjectPersistence. Этот класс обладает одной характерной особенностью – он скрывает в себе не только создание XML-описаний, но и создание необходимой базы данных. Рассмотрим простейший пример использования ObjectPersistence.
Класс ObjectPersistence спроектирован таким образом, что для его использования не обязательно предварительно создавать базу данных, настраивать XML-схемы данных – все это делается внутри реализации ObjectPersistence. Так, в приведенном выше примере на SQL Server будет создана база данных Persistence, и в нее будет добавлена таблица с именем Customer. Конечно, не в каждом проекте можно допустить подобные вольности со стороны библиотеки доступа к данным, но для простейших реализаций – это замечательная возможность скрыть ненужные детали. Итог Технологии доступа к данным в .NET Framework 1.2 содержат множество полезных нововведений, но если для ADO.NET это скорее эволюционные изменения, связанные с простым расширением библиотеки, то ObjectSpaces является совершенно новым продуктом, который может кардинальным образом изменить подход к работе с данными. Конечно, в настоящий момент работа над библиотекой еще далека от завершения. К моменту выхода VisualStudio «Whidbey» мы сможем увидеть в ней массу изменений, начиная с использования generics и расширения возможностей OPath, и заканчивая DML-операторами для удаления объектов без предварительного их извлечения. |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|