Работа с LINQ для SQL на платформе .NET Framework осуществляется с помощью классов пространства имен System.Linq и System.Data.Linq.
Перечислим основные классы этих пространств имен.
□ System.Linq:
• Enumerable — предоставляет набор статичных методов для работы с объектами, реализующими интерфейс IEnumerable<T>.
• Queryable — предоставляет набор статичных методов для работы с объектами, реализующими интерфейс IQueryable<T>.
Методы этих классов, вроде Where, Select, Sum и др., используются в любом LINQ-выражении для построения запросов, обработки и фильтрации данных.
□ System.Data.Linq:
• DataContext — основной объект для работы с LINQ для SQL, предоставляет контекст базы данных, через который осуществляется доступ ко всем сущностям базы данных;
• EntitySet<TEntity>, EntityRef<TEntity> (структура) — обеспечивают связь между сущностями в LINQ для SQL;
• Table<TEntity> — представляет таблицу с возможностью изменения объектов;
• CompiledQuery — предоставляет возможность компилировать и повторно использовать запросы.
Контекст базы данных, наследующий от класса DataContext, в LINQ для SQL принято создавать с помощью мастера, который автоматически сгенерирует LINQ для SQL-классов. После такой генерации работа с объектной моделью становится очень простой, например, приведенный в разделе ADO.NET пример в исполнении LINQ для SQL будет выглядеть так:
using (MyDatabaseDataContext dataContext = new MyDatabaseDataContext())
{
string phone = dataContext.Customers
.Where(x => x.name == "Сергей Петров")
.FirstOrDefault().phone;
}
Согласитесь, это заметно более простое решение по сравнению с вариантом, написанным с использованием ADO.NET Dataset.
Entity Framework
Entity Framework можно использовать только на .NET Framework версии 3.5 с установленным пакетом обновления SP1. Для работы с Entity Framework предлагаются следующие пространства имен: System.Data.Entities, System.Data.Objects, System.Data.EntityClient и др.
В отличие от LINQ для SQL модель данных Entity Framework (EDM) состоит из трех частей:
□ концептуальная модель (CSDL) — позволяет создавать сущности, не равнозначные сущностям базы данных, например, комплексные сущности, состоящие из элементов нескольких таблиц, или сущности, наследующие от других сущностей;
□ модель хранения данных (SSDL) — определяет логическую модель базы данных;
□ модель сопоставления хранения данных и концептуальной модели (MSL) — определяет, как логическая модель хранения базы данных сопоставляется с концептуальной моделью.
При работе с Entity Framework в Visual Studio 2008 SP1 предлагается мастер автоматического создания модели на базе заданных объектов базы данных. Вы можете использовать его для генерации всех трех частей EDM. Результатом работы мастера станет файл *.edmx, который будет содержать все три модели сразу. Контекст базы данных и отображение на классы C# будут сгенерированы в другой файл *.Designer.cs.
После создания мастером модели EDM вы сможете манипулировать концептуальной моделью, моделью хранения и моделью сопоставления с помощью специального визуального дизайнера Entity Framework. Этот дизайнер, кроме всего прочего, позволяет выполнять и такие операции, как валидацию модели EDM, обновление модели из базы данных.
Другим отличием Entity Framework от LINQ для SQL является разнообразие доступа к модели данных. Существует три варианта работы с EDM:
□ LINQ для сущностей — аналог LINQ для SQL с полной поддержкой всех особенностей Entity Framework;
□ Entity SQL — особенный язык, диалект SQL, который служит для работы с моделью EDM. Имеет ряд отличий и ограничений по сравнению с обычным SQL;
□ третий вариант совмещает в себе первые два, с помощью LINQ-выражений можно строить запросы на языке Entity SQL.
Подробное описание особенностей Entity Framework или Entity SQL выходит за рамки этой книги. Здесь мы приведем только очевидные отличия LINQ для сущностей от LINQ для SQL:
□ поддержка прозрачного мэппинга отношений "многие-ко-многим" в LINQ для сущностей. LINQ для SQL строго отображает структуру базы данных, поэтому промежуточная таблица также будет отображена, и ее потребуется использовать при работе с такими данными;
□ отсутствие в LINQ для сущностей поддержки методов Single и singleOrDefault, вместо которых рекомендуется использовать First и FirstOrDefault;
□ вместо методов DeleteOnSubmit и SubmitChanges в LINQ для сущностей предложены методы DeleteObject и saveChanges соответственно;
□ вместо метода XXX.InsertOnSubmit предложены обертки (автогенерируемые) AddToXXX, где XXX — это имя отображаемой сущности (таблицы).
Еще одно незначительное отличие в процессе автогенерации моделей с помощью мастеров в Visual Studio представляет собой изменение имени таблицы при отображении на класс в LINQ для SQL. Например, таблица Customers отобразится на класс Customer, без последней буквы "s". При создании классов в Entity Framework мастер не производит такие изменения.
NHibernate
Еще одним вариантом организации доступа к данным может стать популярная ORM-библиотека NHibernate — довольно старый механизм, портированный на платформу .NET Framework из Java-проекта Hibernate. Как ORM, Hibernate давно заслужила право называться зрелой, гибкой, мощной и главное производительной библиотекой. Адаптация под .NET, хотя и не совсем полностью реализует функционал Hibernate версии 3, но предлагает все тот же механизм, сравнимый по мощности и производительности с предком.
NHibernate, как и другие ORM, использует для реализации доступа к данным мэппинг в виде XML-файла. Этот файл должен быть оформлен согласно схеме nhibernate-mapping.xsd, которая идет в комплекте поставки. По традиции названия всех таких файлов мэппинга формируются как class_name.hbm.xml. Такой файл может выглядеть примерно так:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn: nhibernate-mapping-2.2"
namespace="MyNamespace" assembly="MyNamespace">
<class name="Customer" table="Customers">
<id name="customerId">
<column name="customerId" not-null="true" />
<generator class="guid"/>
</id>
<property name="name" />
<property name="phone" />
<property name="address" />
</class>
</hibernate-mapping>
Здесь создается мэппинг класса Customer на таблицу Customers в базе данных, которая содержит ряд полей: customerId, name, phone, address. Для подключения к базе данных должен быть создан другой конфигурационный файл, похожий на этот:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration>
<session-factory xmlns="urn: nhibernate-configuration-2.2">
<property name=''connection.provider">
NHibernate.Connection.DriverConnectionProvider
</property>
<property name=''connection.driver_class">
NHibernate.Driver.SqlClientDriver
</property>
<property name="dialect">
NHibernate.Dialect.MsSql2005Dialect
</property>
<property name="connection.connection_string">