1 Технология ADO.NET Entity Framework / 1. Что такое Entity Framework 2. Создание модели Entity Framework 3. Запросы в модели Entity Framework Одним из основных требований в бизнес-приложениях (и многих других типах приложений) является способность хранить данные в базах данных и извлекать их оттуда. Однако это легче сказать, чем сделать, потому что реляционная схема базы данных не сочетается с иерархией объектов, с которой мы предпочитаем работать в коде. Для создания и заполнения таких иерархий объектов требуется писать большой объем кода для передачи данных от источника приемнику — дружественные объектные модели, которые потом, как правило, достаточно трудно поддерживать. Фактически это был такой мощный источник постоянного разочарования, что многие разработчики обратились к написанию генераторов кода и прочих инструментов, которые автоматически создают код для доступа к базе данных на основе информации о ее структуре. Однако генераторы кода обычно создают взаимно однозначное отображение между структурой базы данных и объектной моделью, что приводит к проблеме объектно-реляционного несоответствия, которая состоит в том, что то, как данные хранятся в базе данных, не обязательно непосредственно связано с тем, как разработчики хотели бы смоделировать данные в виде объектов. Это привело к концепции объектно-реляционного отображения (Object Relational Mapping), где может быть спроектирована идеальная объектная модель для работы с данными в коде, которая затем может быть отображена на схему базы данных. По завершении отображения механизм объектно-реляционного отображения (Object Relational Mapper — ORM) должен взять на себя бремя по переводу между объектной моделью и базой данных, оставляя разработчикам решения бизнес-проблем (а не технологические вопросы работы с данными). Для многих разработчиков технология ORM представляется Святым Граалем для работы с данными из базы данных в виде объектов. Нет недостачи в постоянных жарких дебатах о сильных и слабых сторонах различных вариантов технологии ORM и о том, как должен выглядеть идеальный механизм ORM. Мы не будем разбираться в этих аргументах в данной главе, а просто ознакомимся с технологией ADO.NET Entity Framework ORM от Microsoft. Если обратиться к истории, то с момента возникновения платформы .NET Framework появился ряд средств для доступа к данным в базах данных, и все — под знаменем технологии ADO.NET. Сначала это был низкоуровневый доступ через механизм SqlConnection (и подключения к другим типам баз данных) с использованием таких средств, как читатели данных. Затем появились более высокоуровневые средства доступа с использованием типизированных наборов данных (Typed DataSets). В версии NET Framework 3.5 появилась технология LINQ to SQL, впервые предоставляя встроенное средство для работы с данными как с объектами. Однако в течение длительного времени компания Microsoft не включала механизм ORM в платформу .NET Framework (несмотря на ряд ранних неудачных попыток сделать это с архитектурой ObjectSpaces). К тому времени уже имелся ряд механизмов ORM, доступных для использования с платформой .NET Framework, в числе самых популярных NHibernate и LLBLGen Pro. В конечном итоге компании Microsoft удалось выпустить свой собственный механизм ORM, который она назвала ADO.NET Entity Framework и который вошел в версию .NET Framework 3.5 SP1. Выпуск технологии Entity Framework, несмотря на долгое ожидание, не был безоблачным, более того, многими разработчиками (в том числе и сотрудниками Microsoft со статусом MVP (Most Valuable Professional особо ценный специалист)) была даже подписана петиция протеста. Однако в версии .NET Framework 4 в технологию Entity Framework было добавлено много 2 улучшений, которые существенно уменьшили количество недостатков (и недовольных продуктом). Эта глава проведет вас через процесс создания модели базы данных в соответствии с технологией Entity Framework и ознакомит с тем, как использовать эту технологию для запросов и обновлений базы данных. Технология Entity Framework это огромная тема, и имеются целые книги, посвященные использованию данного продукта. Осветить все его особенности невозможно, так что эта глава посвящена обсуждению только лишь некоторых из его основных функций и тому, как начать работу и создать базовую модель. Модели Entity Framework, создаваемые в данном разделе, будут использованы и далее, где в примерах потребуется доступ к базе данных. 1 Что такое Entity Framework По существу, технология Entity Framework реализует объектно-реляционное отображение (ORM). Объектно-реляционное отображение позволяет создавать концептуальную модель объекта, отображать его на базу данных, а механизм ORM будет заботиться о переводе ваших запросов из объектной модели в запросы к базе данных, возвращая данные в виде объектов, которые вы определили в своей модели. 1.1 Сравнение с технологией LINQ to SQL Стандартный вопрос от разработчиков об отношениях между технологиями Entity Framework и LINQ to SQL, и какую технологию следует применять при создании приложений, ориентированных на работу с данными. Рассмотрим преимущества каждой из упомянутых технологий. Преимущество технологии LINQ to SQL над технологией Entity Framework Легкость обучения и создания запросов. Преимущества технологии Entity Framework над технологией LINQ to SQL Позволяет создавать концептуальную модель базы данных, а не просто взаимно однозначное соответствие базы данных объектам (например, когда один объект отображается на несколько таблиц базы данных, поддержка наследования, определение сложных свойств). Возможность генерации базы данных на основе модели. Поддержка баз данных, отличных от SQL Server. Поддержка отношений “многие ко многим”. Поддержка отложенной загрузки. Синхронизация, обеспечивающая обновление баз данных без потерь настроек вашей модели. , Продолжает развиваться в отличие от LINQto SQL. 1.2 Концепции Entity Framework Ниже описаны некоторые из важных концепций Entity Framework, а также термины, использующиеся в этой главе. Сущностная модель (Entity Model). Модель, которую вы создаете с использованием технологии Entity Framework, состоит иатрех частей. Концептуальная модель. Представляет объектную модель, включая сущности, их свойства и связи между ними. 3 Модель хранения. Представляет структуру базы данных, включая цы/представления/хранимые процедуры, столбцы, внешние ключи и т.д. табли- Отображение. Представляет “клей”, соединяющий модель хранения и концептуальную модель (т.е. слой между базой данных и объектной моделью), путем отображения одной на другую. Каждая из этих частей поддерживается технологией Entity Framework на основе языка XML с использованием предметно-ориентированного языка (domain-specific language — DSL). Сущность (Entity). По сути, сущности представляют собой объекты (со свойствами), на которые отображается модель базы данных. Набор сущностей (Entity Set). Представляет собой коррекцию данных сущностей. Сущность можно представлять как строку в базе данных, а набор сущностей — как таблицу. Связь (Association). Связи определяют взаимоотношения сущностей в вашей сущностной модели и концептуально представляют собой то же, что и взаимоотношения в базе данных. Отображение (Mapping). Представляет собой базовую концепцию механизма ORM. По сути, это слой перевода из реляционной схемы базы данных в объекты кода. 2 С чего начать Для демонстрации некоторых различных возможностей технологии Entity Framework пример в этом разделе использует учебную базу данных AdventureWorksLT, разработанную компанией Microsoft как один из образцов баз данных для SQL Server. База AdventureWorksLT представляет собой упрощенный вариант полной базы данных AdventureWorks, что упрощает демонстрацию концепций технологии Entity Framework без тех дополнительных сложностей, которые создает использование полной базы данных. База данных AdventureWorksLT доступна для загрузки с веб-сайта CodePlex в виде сценария, расположенного по адресу http://professionalvisualstudio.com/1ink/1029A Adventure Works Cycles представляет собой вымышленную компанию по продаже цепей для велосипедов, а база данных AdventureWorksLT используется для хранения и доступа к данным о продажах. Следуйте подробным инструкциям с веб-сайта CodePlex о том, как установить базу данных из загруженного сценария в экземпляр SQL Server (версии SQL Server Express Edition вполне достаточно), который находится на вашем компьютере или доступен для него. Итак, перейдем к созданию проекта, который содержит модель Entity Framework этой базы данных. Начните с открытия диалогового окна New Project и создания нового проекта. Учебный проект, который будет создан в этой главе, использует шаблон проекта WPF. Вы будете выводить данные в управляющем элементе WPF DataGrid, определенном в файле MainWindow.xaml под именем dgEntityFrameworkData. Теперь, когда у вас есть проект, который будет размещать и выполнять запросы к модели Entity Framework, пришло время для создания этой модели. 3 Создание сущностной модели Есть два способа создания модели. Как правило, модель создается на основе структуры существующей базы данных, однако с помощью технологии Entity Framework можно начать и с пустой модели, а затем заставить механизм Entity Framework генерировать структуру базы данных на ее основе. 4 Учебный проект использует для создания модели первый метод, основанный на структуре базы данных AdventureWorksLT. 3.1 Мастер Entity Data Model Wizard Откройте диалоговое окно Add New Item (Добавить новый элемент) вашего проекта, перейдите к категории данных и выберите ADO.NET Entity Data Model (Модель ADO.NET EDM) в качестве шаблона (рис. 1). Дайте модели имя AdventureWorksLTModel. edmx. Рисунок 1 При этом будет запущен мастер Entity Data Model Wizard (Мастер модели EDM), который поможет начать построение модели Entity Framework. Вы увидите диалоговое окно, показанное на рис. 2, которое позволяет выбрать, хотите ли вы автоматически создать модель на основе базы данных Generate from Database (Создать из базы данных) или начать с пустой модели Empty Model (Пустая модель). Пустая модель полезна, если вы хотите создать модель с нуля и либо отобразить ее на данную базу данных вручную, либо позволить Entity Framework создать базу данных на основе вашей модели. Однако, как указывалось ранее, здесь будет создана модель на основе базы данных AdventureWorksLT, так что вам надо выбрать вариант Generate from Database (Создать из базы данных) и попросить мастера помочь создать модель на основе существующей базы данных. На следующем шаге нужно создать соединение с базой данных (рис. 3). Можете выбрать из выпадающего списка последнее подключение к базе данных, но если его там нет (например, если это первое подключение к базе данных), создайте новое подключение. Для этого щелкните на кнопке New Connection (Создать соединение…) и пройдите стандартную процедуру выбора экземпляра SQL Server, учетных данных для аутентификации и, наконец, самой базы данных. 5 Рисунок 2 Рисунок 3 6 Если в качестве данных для аутентификации вы используете имя пользователя и пароль, можно не включать их в строку подключения (которая содержит детали, необходимые для подключения к базе данных) при ее сохранении, потому что эта строка хранится в виде обычного текста, так что любому, кто увидит ее, обеспечен доступ к базе данных. В этом случае, чтобы создать подключение к базе данных, следует передавать указанные данные модели перед выполнением запросов. Если вы не установите флаг сохранения настроек соединения в файле App.config, то вам потребуется передавать модели не только упомянутые имя и пароль, но и другую информацию о подключении к базе данных. На следующем шаге мастер использует созданное на предыдущем шаге подключение для соединения с базой данных и извлечения ее структуры (т.е. ее таблиц, представлений и хранимых процедур), которые отображаются в дереве выбора элементов, которые должны быть включены в вашу модель (рис. 4). Рисунок 4 Другие настройки, которые могут быть указаны в этом окне, включают следующее. Pluralize or Singularize Generated Object Names (Формировать имена объектов во множественном или единственном числе). Будучи установлена, эта настройка принимает имя таблицы/представления/хранимой процедуры и использует множественное или единственное число в названии, в зависимости от того, как имя используется в модели (коллекции будут использовать форму множественного числа, объекты единственное число и т.д.). Include Foreign Key Columns in the Model (Включить столбцы внешних ключей в модель). Предыдущая версия Entity Framework для столбцов внешних ключей в объектах не создавала свойства, делая это только для создания отношений. Однако в ряде сценариев это не подходит, делая невозможным решение ряда простых задач в связи с отсутствием указанных свойств. В новой же версии можно потребовать их включения в объекты с помощью указанной настройки. . 7 Model Namespace (Пространство имен модели). Эта настройка позволяет указать пространство имен, в котором будут создаваться все классы, связанные с моделью. По умолчанию модель существует в своем собственном пространстве имен (которое по умолчанию совпадает с именем модели, введенном в диалоговом окне Add New Item (Добавление нового элемента)), а не в пространстве имен проекта по умолчанию, чтобы избежать конфликта с существующими в проекте классами с теми же именами. Выберите в базе данных все таблицы, которые должны быть включены в модель. После щелчка на кнопке Finish (Готово) будет создана модель Entity Framework, которая отображается на базу данных. Здесь вы можете просматривать модель в Entity Framework и настраивать ее согласно вашим требованиям (а также вашему вкусу или стандартам), чтобы сделать ее идеальной для запросов в вашем коде. 3.2 Проектировщик Entity Framework После создания модели Entity Framework она открывается в проектировщике Entity Framework, показанном на рис. 5. Рисунок 5 Вы увидите, что. проектировщик автоматически расположил все созданные мастером объекты, показывая созданные между ними связи. Можете перемещать объекты по поверхности проектировщика, и он автоматически будет перемещать линии связей и пытаться аккуратно расположить их на экране. Объекты автоматически выравниваются по сетке, которую можно увидеть, если выбрать команду GridShow Grid (СеткаПоказать сетку) контекстного меню, вызываемого щелчком правой кнопки мыши. Отключить привязку к сетке можно щелчком правой кнопкой мыши на поверхности проектировщика и снятия флажка GridShow Grid (СеткаПоказать сетку). При этом вы получаете возможность более точного управления диаграммой макета, но при использовании привязки схема все же получается более аккуратной. При перемещении объектов диаграммы (или добавлении новых) можно запутать диаграмму и получить массу пересекающихся линий связей, проходящих во всех направлениях. Это не беда всегда можно щелкнуть правой кнопкой мыши на поверхности проектировщика и выбрать в контекстном меню команду DiagramsLayout Diagram (СхемаСхема макета ), что заставит проектировщик аккуратно расположить объекты в соответствии со своим собственным 8 алгоритмом. Модели Entity Framework могут быстро стать большими и трудными для навигации в проектировщике Entity Framework. К счастью, в нем имеется несколько инструментов, делающих навигацию немного более легкой. Проектировщик позволяет увеличивать и уменьшать масштаб с помощью кнопок масштабирования в нижнем правом углу (ниже вертикальной полосы прокрутки, как показано на рис. 6). Кнопка между кнопками увеличения/уменьшения масштабирует изображение до величины 100%. Для увеличения до заранее заданной величины щелкните правой кнопкой мыши на поверхности проектировщика и выберите один из вариантов в меню Zoom (Масштаб). В этом меню вы также найдете команду Zoom to Fit (В размер окна), а также команду Custom (Настройка), которая выводит диалоговое окно, позволяющее ввести конкретное значение масштаба. Кроме того, выбор объекта в окне инструмента Properties (из выпадающего списка Свойства) автоматически выбирает нужный объект в проектировщике и выводит его в поле зрения; щелчок правой кнопкой мыши на объекте (список Типы сущностей) в окне инструментов Model Рисунок 6 Browser (Обозреватель моделей) (оно будет описано чуть позже) и выбор команды контекстного меню Show in Designer (Показать в конструкторе) делает то же самое. Так очень легко перейти к конкретным объектам в проектировщике, и по необходимости вы сможете вносить любые изменения в объекты. Чтобы минимизировать пространство, занятое объектом, щелкните на пиктограмме в правом верхнем углу объекта. Кроме того, можете сворачивать и разворачивать группы Properties (Свойства) и Navigation Properties (Свойства навигации), щелкая на пиктограммах +/- слева от них. На рис. 7 показан объект в нормальном развернутом состоянии, со свернутыми свойствами и в полностью свернутом состоянии. Вы можете развернуть все свернутые объекты одновременно, щелкнув правой кнопкой мыши на поверхности проектировщика и выбрав в контекстном меню команду Diagrams Expand All (СхемаРазвернуть все). Точно так же можно свернуть все объекты, воспользовавшись командой DiagramCollapse All (СхемаСвернуть все) контекстного меню, вызываемого щелчком правой кнопки мыши. Рисунок 7 9 Визуальное представление модели может оказаться полезным в проектной документации вашего приложения. Проектировщик предоставляет средства для сохранения схемы модели в файле изображения. Щелкните правой кнопкой мыши в любом месте проектировщика и выберите команду DiagramExport as Image (СхемаЭкспорт в виде изображения) из контекстного меню. Открывшееся диалоговое окно Save As (Сохранить) позволит выбрать место для сохранения изображений. Обратите внимание на то, что по умолчанию выполняется сохранение в формате BMP. Но в выпадающем списке Save As Туре (Тип файла) можно выбрать и другие форматы для сохранения, такие как JPEG, GIF, PNG и TIFF. Пожалуй, наилучший компромисс между качеством изображения и размером файла предлагает формат PNG. Часто бывает полезно отобразить типы каждого свойства объекта (особенно при сохранении диаграммы для использования в документации). Эту возможность можно включить с помощью команды Scalar Property FormatDisplay Name and Type (Формат скалярных свойствОтображать имя и тип) контекстного меню, вызываемого щелчком правой кнопки мыши. Вернуться к показу только имени свойства можно с помощью команды Scalar Property FormatDisplay Name (Формат скалярных свойствОтображать имя) контекстного меню, вызываемого щелчком правой кнопки мыши. Как и у большинства проектировщиков в Visual Studio, инструментальные окна Toolbox и Properties являются неотъемлемой частью проектировщика. Окно Toolbox (рис. 8) содержит три элемента управления: Entity, Association и Inheritance. Как использовать эти элементы управления, вы узнаете в ближайшее время. В окне Properties отображаются свойства выбранного в проектировщике элемента (или элементов), что позволяет по мере необходимости изменять их значения. В дополнение к окнам Toolbox и Properties проектировщик Entity Framework включает также два других инструментальных окна Model Browser (Обозреватель моделей) и Mapping Details, характерных только для него и предназначенных для работы с данными.