четверг, января 17, 2008

Entity Framework - что такое EDM?

Если вы решили познакомится с Entity Framework то термин Entity Data Model будет, пожалуй, первым, с чем придется столкнуться:

В основу архитектуры Entity Framework положены две основные концепции. Первая, и основная из них - Entity Data Model, вторая – Entity Client. Причем между ними есть некоторые противоречия. Как и почему они возникли - тема отдельного разговора, а сегодня я хочу рассказать об Entity Data Model (EDM).

EDM - это фундамент на котором возведено все здание Entity Framework (EF). EDM - это также та вещь, которая отличает EF от множества других ORM движков. Обычно ORM движки опираются на объектную модель приложения в виде классов, и предоставляют различные механизмы маппинга классов домена приложения на таблицы в реляционной БД. Для этих целей используются либо Xml манифесты (описания), либо характерный для .Net механизм атрибутов. Т.е. фактически обычно ORM движки используют метаданные в виде описания маппинга объектов на реляционные структуры. EF помимо описания маппинга вводит описание объектной модели, которое называется Conceptual Model, и реляционной модели - Storage Model. Таким образом EDM состоит из трех частей:
  • Conceptual schema

  • Storage schema

  • Mapping specification

Все это хранится в Xml файле с расширением edmx. Интересно, что судя по XML схеме, один edmx может содержать несколько экземпляров концептуальных схем, схем БД и спецификаций маппинга (только вот дизайнер в 2008 студии всего этого не поддерживает).

Для чего это сделано? Во-первых, во имя давней идеи отделения логического слоя домена приложения от слоя хранения данных. Действительно, в EF сущностях, которые представлены классами, генерируемыми по Conceptual Schema ничего не напоминает о БД. Кстати, атрибуты, которыми помечены эти классы и их свойства, предназначены вовсе не для обеспечения маппинга на БД, а для связи классов с сущностями концептуальной модели. В документации EF неоднократно подчеркивается, что концептуальная модель может разрабатываться отдельно от модели БД, и при этом несколько различных приложений каждое со своей концептуальной моделью могут маппироваться на одну и ту же модель БД (в рамках нескольких EDM, конечно). Справедливо и обратное: модель БД может изменяться отдельно от концептуальной модели (в определенных пределах, конечно).

Во-вторых, EF вводит дополнительный слой абстракции в виде концептуальной модели. Подобно тому, как WCF предлагает новую парадигму разработки «contract first», при следовании которой сначала определяется контракт сервиса и данных а затем их реализация, так EF предлагает парадигму «model first». Сначала разрабатываем концептуальную модель, которая суть модель домена приложения, а уже классы по этой модели автоматически будут сгенерированы инструментами EF. Концептуальная модель разрабатывается в привычных объектных терминах: сущности (entities), отношения наследования (inheritance and hierarchу), ассоциации (associations). Есть и специфические вещи, которые не дают нам забыть, что EF это все-таки ORM и где-то там внизу существует база данных. К таким вещам относится EntitySet и AssociationSet – логические контейнеры для сущностей и ассоциаций одного типа. Если сущности (entity) соответствует класс C# или тип, то EntitySet - это коллекция объектов. Важно отметить, что свой EntitySet полагается не каждой сущности. Для иерархии сущностей связанных наследованием существует только один EntitySet соответствующий корневой родительской сущности.

Для создания и редактирования EDM в VS2008 есть визард и дизайнер.

К сожалению, с дизайнером пока (beta3) связано большое количество багов. К тому же дизайнер поддерживает не все возможности EDM, в частности в дизайнере нельзя создать ComplexType и задать его в качестве Scalar Property сущности. Надеюсь это временные трудности.

Плохо другое. Как я уже говорил, наличие EDM вроде-бы ненавязчиво подталкивает нас к использованию сценария разработки «model first». Разрабатываем модель сущностей домена приложения и их связей, затем разрабатываем структуру БД ориентируясь уже на готовую модель домена и особенности конкретной БД, а затем описываем маппинг сущностей домена на объекты БД. А все исходники генерируются автоматически. Так вот, если вы попробуете так работать при помощи имеющихся инструментов VS2008, то у вас ничего не получится. Можно создать пустую модель при помощи визарда. Можно создать в нем сущности, их свойства и связи при помощи дизайнера, хотя это очень не удобно (в аналогичных дизайнерах SQL2005 все гораздо удобней). Но когда дело дойдет до описания схемы БД (Storage schema), вам придется иметь дело с голым XML. Существующий визард «Update model from Database» одновременно с загрузкой Storage schema удалит все незамапленные сущности, т.е. всю вашу работу. Поэтому пока более предпочтительным выглядит другой сценарий. Сначала создаете БД (или берете готовую). Натравливаете на нее визард создания EDM, а затем редактируете уже готовые сущности, описываете наследование сущностей (дизайнер это позволяет), редактируете свойства и правите маппинг.

Роль EDM не ограничивается design time и генерацией классов по xml описаниям сущностей в модели. EDM используется и в runtime. В ранних CTP соответствующие XML файлы помещались студией после компиляции проекта в TargetDir рядом с файлом сборки. В beta 3 появилась возможность указать в свойствах дизайнера EDM куда помещать метаданные: как и прежде в файлы, либо в ресурсы сборки. Первый вариант удобен тем, что позволяет изменить маппинг и схему БД без перекомпиляции сборки (до известных пределов конечно). Второй вариант позволяет избавиться от csdl ssdl и msl файлов при развертывании приложения. Способ размещения файлов влияет на формат строки подключения EF. Впрочем, ничто не мешает нам комбинировать оба спсоба: при компиляции разместить EDM в ресурсы сборки, а в последствии, при необходимости изменить, к примеру, маппинг можно выпустить отдельный msl файл и соответствующим образом изменить строку подключения.

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

5 комментариев:

Анонимный комментирует...

http://dev.net.ua/blogs/shatokhin/pages/5129.aspx
http://dev.net.ua/blogs/shatokhin/pages/5131.aspx
Видео по Entity Framework c конференции "Дни разработчиков 2007", которая проходила в Киеве

Анонимный комментирует...

Черезвычайно полезная и интересная статья. Пожалуйста продолжайте писать!

Constantine

Manticora комментирует...

Полезная статья. Большое спасибо.

Анонимный комментирует...

Хорошая статья. Требую добавки!

Анонимный комментирует...

Прочитал много статей про EF, но только сейчас осознал, чем принципиально отличается EF от Linq2Sql.