Казахстан, Алматы, Гимназия им. Ахмета Байтурсынова №139, 2008 |
Проектирование баз данных и работа с ними Веб-приложений. LINQ, ADO.NET Entities, DDD
10.1.2.3. Пример использования LINQ to SQL
Для создания объектной модели для базы данных, классы должны быть приведены в соответствие с сущностями, хранящимися в базе данных. Можно выделить три способа реализации такого приведения [8] – можно задавать атрибуты для существующих объектов, можно использовать специальное средство, позволяющее автоматически сгенерировать объекты и использовать утилиту командной строки SQLMetal.
- Объектно-реляционный конструктор. Этот конструктор предоставляет многофункциональный пользовательский интерфейс для создания объектной модели из существующей базы данных. Данное средство, являющееся частью интегрированной среды разработки Visual Studio, лучше всего подходит для баз данных небольшого или среднего размера.
- Средство создания кода SQLMetal. По своему набору параметров эта консольная программа несколько отличается от Объектно-реляционного конструктора. Данное средство лучше всего подходит для моделирования больших баз данных.
- Редактор кода. Можно написать собственный код с помощью редактора кода Visual Studio или другого редактора кода. Этот подход может привести к большому числу ошибок, поэтому при наличии существующей базы данных, которую можно использовать для создания модели с помощью Объектно-реляционного конструктора или программы SQLMetal, использовать его не рекомендуется. Однако редактор кода становится ценным инструментом, когда требуется уточнить или изменить код, уже созданный с помощью других средств.
Используем последний способ, задав атрибуты для существующих объектов [3]:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Linq; using System.Data.Linq.Mapping; using System.Data.SqlClient; namespace LinqtoSQL { [Table(Name = "Customers")] public class Customer { [Column] public string CustomerID { get; set; } [Column] public string City { get; set; } public override string ToString() { return CustomerID + "\t" + City; } } class Program { static void Main(string[] args) { DataContext db = new DataContext (@"Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\NORTHWND.MDF; Integrated Security=True; User Instance=True"); var results = from c in db.GetTable<Customer>() where c.City == "Москва" select c; foreach (var c in results) Console.WriteLine("{0}\t{1}", c.CustomerID, c.City); Console.ReadKey(); } } }
В этом приложении есть класс Customer, который отображает таблицу Customers, и имеет поля CustomerID и City, отображающие поля этой таблицы. Объект класса DataContext задает входную точку в базу данных и имеет метод GetTable, который возвращает коллекцию определенного типа, в данном случае типа Customer.
В результате выполнения программы на экран будут выведены идентификаторы и города проживания тех заказчиков, которые живут в Москве.
На рис. 10.10 приведено отображение LINQ to SQL.
Следующее пример демонстрирует автоматическое создание объектов отображения с помощью Объектно-реляционного конструктора и работу с хранимыми процедурами.
Для начала необходимо добавить файл LINQ to SQL classes. Затем в окне Server Explorer следует развернуть дерево базы данных Northwind и перетащить нужные таблицы и хранимые процедуры в окно файла отображения на панель методов. Для данного примера будет достаточно перетащить хранимую процедуру Ten Most Expensive Products (рис. 10.11).
Хранимая процедура извлекает из таблицы Products 10 самых дорогих продуктов и их цены:
USE [Northwind] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER procedure [dbo].[Ten Most Expensive Products] AS SET ROWCOUNT 10 SELECT Products.ProductName AS TenMostExpensiveProducts, Products.UnitPrice FROM Products ORDER BY Products.UnitPrice DESC
Для того чтобы вызвать эту процедуру из программы на языке C# и вывести результаты, достаточно написать всего 3 строки кода:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Linq; using System.Data.Linq.Mapping; namespace LinqtoSQL { class Program { static void Main(string[] args) { var db = new northwindDataContext(); foreach (var r in db.Ten_Most_Expensive_Products()) Console.WriteLine(r.TenMostExpensiveProducts + "\t" + r.UnitPrice); Console.ReadKey(); } } }
Обратите внимание, что входная точка в базу данных теперь создается конструктором класса northwindDataContext (в общем случае класс будет называться так: {имя файла отображения} DataContext ), которому больше не нужно передавать параметром строку соединения в явном виде.
10.1.3. ADO.NET Entity Framework
ADO.NET Entity Framework (EF) – объектно-ориентированная технология доступа к данным, является object-relational mapping (ORM) решением для .NET Framework от Microsoft [9]. Предоставляет возможность взаимодействия с объектами как посредством LINQ в виде LINQ to Entities, так и с использованием Entity SQL. Для облегчения построения Веб-решений используется как ADO.NET Data Services, так и связка из Windows Communication Foundation и Windows Presentation Foundation, позволяющая строить многоуровневые приложения, реализуя один из шаблонов проектирования MVC, MVP или MVVM.
Платформа ADO.NET Entity Framework позволяет разработчикам создавать приложения для доступа к данным, работающие с концептуальной моделью приложения, а не напрямую с реляционной схемой хранения. Ее целью является уменьшение объема кода и усилий по обслуживанию приложений, ориентированных на обработку данных. Приложения Entity Framework дают следующие преимущества [10].
- приложения могут работать концептуальной моделью в терминах предметной области – в том числе с наследуемыми типами, сложными элементами и связями;
- приложения освобождаются от жестких зависимостей от конкретного ядра СУБД или схемы хранения;
- сопоставления между концептуальной моделью и схемой, специфичной для конкретного хранилища, могут меняться без изменения кода приложения;
- разработчики имеют возможность работать с согласованной моделью объектов приложения, которая может быть сопоставлена с различными схемами хранения, которые, возможно, реализованы в различных системах управления данными;
- несколько концептуальных моделей могут быть сопоставлены с единой схемой хранения;
- поддержка интегрированных в язык запросов ( LINQ ) обеспечивает во время компиляции проверку синтаксиса запроса относительно концептуальной модели.
10.1.3.1. Компоненты Entity Framework
Платформа Entity Framework представляет собой набор технологий ADO.NET, обеспечивающих разработку приложений, связанных с обработкой данных [10]. Архитекторам и разработчикам приложений, ориентированных на обработку данных, приходится учитывать необходимость достижения двух совершенно различных целей. Они должны моделировать сущности, связи и логику решаемых бизнес-задач, а также работать с ядрами СУБД, используемыми для сохранения и получения данных. Данные могут распределяться по нескольким системам хранения данных, в каждой из которых применяются свои протоколы, но даже в приложениях, работающих с одной системой хранения данных, необходимо поддерживать баланс между требованиями системы хранения данных и требованиями написания эффективного и удобного для обслуживания кода приложения.
В Entity Framework разработчики получают возможность работать с данными, представленными в форме относящихся к конкретным доменам объектов и свойств, таких как клиенты и их адреса, не будучи вынужденными обращаться к базовым таблицам и столбцам базы данных, где хранятся эти данные. Такая возможность появляется благодаря переходу на более высокий уровень абстракции, на котором разработчики могут работать с данными, применяя меньший объем кода для создания и сопровождения приложений, ориентированных на работу с данными.
Платформа Entity Framework является компонентом .NET Framework, поэтому приложения Entity Framework можно запускать на любом компьютере, на котором установлен .NET Framework 3.5 с пакетом обновления 1 (SP1).
10.1.3.1.1. Применение концептуальных моделей на практике
Давно известный и широко применяемый принцип проектирования в моделировании данных состоит в разделении модели данных на следующие три части: концептуальная модель, логическая модель и физическая модель. Концептуальная модель определяет сущности и связи в моделируемой системе. Логическая модель для реляционной базы данных обеспечивает нормализацию сущностей и связей в целях создания таблиц с ограничениями внешнего ключа. В физической модели учитываются возможности конкретной системы обработки данных путем определения зависящих от ядра базы данных подробных сведений о хранении данных, которые касаются секционирования и индексирования.
Физическая модель совершенствуется администраторами базы данных в целях повышения производительности, но программисты, которые разрабатывают код приложения, в основном вынуждены ограничиваться работой с логической моделью, подготавливая SQL-запросы и вызывая хранимые процедуры. Концептуальные модели в основном используются как инструмент для представления и обмена мнениями по поводу требований к приложению, поэтому чаще всего служат в качестве почти неизменных схем, которые рассматриваются и обсуждаются на ранних стадиях проекта, после чего перестают быть предметом внимания.
Платформа Entity Framework придает значимость концептуальным моделям, позволяя разработчикам выполнять запросы к сущностям и связям в концептуальной модели; при этом для перевода этих операций в команды, зависящие от источника данных, применяется сама платформа Entity Framework. Это позволяет отказаться от применения в приложениях жестко заданных зависимостей от конкретного источника данных. Концептуальная модель, модель хранения и их сопоставление выражаются во внешней спецификации, известной также как модель Entity Data Model (EDM). Модель хранения и сопоставление могут изменяться по мере необходимости, не требуя изменений в концептуальной модели, классах данных и коде приложения. Модели хранения зависят от поставщика, поэтому можно работать с согласованной концептуальной моделью через различные источники данных.
Модель EDM определяется следующими тремя файлами модели и сопоставления, которые имеют соответствующие расширения имен файлов.
- Файл на языке CSDL (с расширением CSDL) определяет концептуальную модель.
- Файл на языке SSDL (с расширением SSDL). Определяет модель хранения данных, которая называется также логической моделью.
- Файл на языке MSL (с расширением MSL) определяет сопоставление модели хранения и концептуальной модели.
В Entity Framework эти файлы модели и сопоставления на основе XML используются для преобразования операций создания, чтения, обновления и удаления, выполняемых над сущностями и связями концептуальной модели, в эквивалентные операции в источнике данных (рис. 10.12). Модель EDM поддерживает даже сопоставление сущностей в концептуальной модели с хранимыми процедурами в источнике данных.
В модели EDM сущности и их связи моделируются с использованием двух основных типов.
- EntityType : абстрактная спецификация подробных сведений о структуре данных в домене приложения.
- AssociationType: логическое соединение между типами.
Схема проектирования модели EDM определяет структуру, семантику, ограничения и связи сущностей в домене приложения. В реализации служб объектов модели EDM концептуальная схема сопоставляется с EDM-схемой, которая содержит метаданные, описывающие модель хранения (обычно это таблицы в базе данных). Концептуальная схема используется для формирования классов программируемой модели объектов, которая применяется в коде приложения. Концептуальная схема и схема хранения используются также в технологии Entity Framework для проверки, выполнения запросов и обновления данных приложения во время выполнения.