Подходы для работы с Entity Framework

159

При использовании Entity Framework в приложении существует три подхода для организации взаимодействия Entity Framework с базой данных: Code-First, Model-First и Database-First. В этой статье мы кратко рассмотрим эти подходы и проведем их сравнительный анализ, а более подробное описание каждого из подходов с использованием примеров будет приведено в следующих статьях.

Подход Code-First

Подход Code-First, который впервые появился в Entity Framework 4.1, обычно используется, когда у вас есть уже существующее приложение, содержащее модель данных. Эта модель, как правило, описывается с помощью нескольких классов и кода взаимодействия между этими классами. Например, вы можете создать класс по имени Customer, который будет содержать данные покупателя в интернет-магазине:

public class Customer
{
    // Определить поля, которые используются в базе данных
    public int CustomerId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string City { get; set; }
    public int Age { get; set; }
    public DateTime BirthDate { get; set; }
}

Вы можете использовать этот класс модели в своем приложении без создания базы данных. Добавив дополнительный код, вы могли бы хранить объекты этого класса, например, на диске в формате XML или в памяти рабочего процесса программы. Однако когда ваше приложение расширяется и становится крупным, эти данные необходимо будет хранить в базе данных. Эта та точка, в которой и начинает работать подход Code-First – вы можете использовать существующий код для создания базы данных не беспокоясь о деталях реализации базы данных (этим займется Entity Framework), а вы можете сфокусировать свое внимание на коде.

Важно отметить, что класс, представляющий модель данных, должен иметь поле Id, которое будет использоваться в таблице базы данных в качестве первичного ключа. Entity Framework автоматически находит такое поле с помощью механизма рефлексии (в его имени должна содержаться строка “Id”, поэтому поле CustomerId в примере выше будет автоматически использоваться в качестве первичного ключа.) Это ограничение можно обойти, использовав свойство с произвольным именем и помеченное специальными атрибутами метаданных C#, которые используются в Entity Framework. Здесь мы их описывать не будем, я лишь заострил свое внимание на этом моменте, потому что он показывает, что любые настройки первичных и внешних ключей, ограничения между таблицами и т.д. при подходе Code-First указываются в модели (т.е. в управляемом коде C#), а потом проецируются на базу данных.

Подход Code-First появился позже подходов Model-First и Database-First и, как вы уже поняли, больше всего подходит для разработчиков, которые хотят писать код, а не работать с дизайнером модели EDM или средствами работы с базами данных (SQL Server Management Studio и T-SQL). Вы можете создать модель для вашего приложения, используя объекты CLR (Common Language Runtime) и специальные объекты POCO (Plain Old CLR Object).

При проектировании приложений с подходом Code-First, вы сначала создаете классы модели данных не обращая никакого внимания на Entity Framework. После того, как вам понадобилось работать с базой данных, вы используете различные инструменты, которые проецируют структуру базы данных из созданной модели классов. После этого вы можете вернуться к этой модели в коде и, например, изменить ее. Эти изменения затем можно будет отразить в базе данных используя все те же инструменты.

Важным нововведением версии Entity Framework 5 в плане подхода Code-First, является то, что созданная модель классов теперь сразу является сущностной моделью данных EDM (Entity Data Model), поэтому отпала необходимость использовать файл EDMX. В более ранних версиях разработчику, использующему подход Code-First, приходилось добавлять отношения между моделью классов и файлом EDMX, т.е. отображать любые изменения модели сразу в двух местах. Очевидно, что этот подход приводил к появлению кучи ошибок, если разработчик забывал синхронизировать эти изменения в обоих файлах.

Чтобы указать среде Visual Studio, что модель классов является моделью EDM, нужно во-первых установить сборки Entity Framework в проект, а во-вторых добавить класс контекста базы данных, унаследованный от класса DbContext, находящегося в пространстве имен System.Data.Entity, как показано в примере ниже (установку Entity Framework и настройку класса контекста мы более подробно будем рассматривать позже):

using System;
using System.Data.Entity;

namespace ProfessorWeb.EntityFramework
{
    public class PwContext : DbContext
    {
        // Это свойство ссылается на таблицу в базе данных
        public DbSet<Customer> Customer { get; set; }
    }
}

Вам не нужно беспокоится о способах взаимодействия с базой данных, Entity Framework определяет ряд вспомогательных методов. Вам не нужно знать деталей подключения и даже имени базы данных. Ниже показан пример вставки данных в таблицу с использованием тестового класса Customer, показанного выше:

public void InsertCustomer()
{
    // Создать объект для записи в БД
    Customer customer = new Customer
    {
        FirstName = "Вася",
        LastName = "Пупкин",
        Age = 27,
        City = "Москва",
        BirthDate = DateTime.Now.AddYears(-27)
    };

    // Создать объект контекста
    PwContext context = new PwContext();

    // Вставить объект в БД и сохранить изменения
    context.Customer.Add(customer);
    context.SaveChanges();
}

Этот код является немного упрощенным, но все же показывает суть работы с Entity Framework. Конечно, вы можете глубже контролировать каждую операцию с базой данных. Этот пример использует максимальную автоматизацию и дает приемлемые результаты, по крайней мере в небольшом приложении. В последующих статьях мы рассмотрим более подробно настройки подхода Code-First, которые можно использовать для удовлетворения конкретных потребностей.

Подход Model-First

Подход Model-First, впервые появившийся в версии Entity Framework 4, применяется разработчиками, которые не хотят использовать инструменты СУБД для создания и управления базами данных, а также не хотят вручную настраивать классы модели EDM. Фактически это самый простой подход при работе с Entity Framework. Проектирование модели происходит в графическом дизайнере EDM среды Visual Studio. Вы могли наблюдать использование Model-First в предыдущей статье, где мы создали простое приложение ASP.NET.

Рабочий процесс создания модели при подходе Model-First начинается в тот момент, когда вы проектируете базу данных. При этом вам необходимы минимальные знания устройства баз данных, например, для настройки отношений между таблицами в графическом дизайнере или указания типов данных SQL полей таблицы.

Как и в случае подхода Code-First, вся работа строится вокруг класса контекста базы данных. Фактически, взаимодействие с базой данных в этих подходах одинаковое. Например, для вставки объекта, используется следующая последовательность действий:

  1. Создать объект модели и наполнить его данными.

  2. Создать класс контекста, унаследованный от DbContext (в подходе Code-First это делается вручную, в Model-First этот класс генерируется автоматически вместе с сущностными классами).

  3. Добавить объект в базу данных, используя класс контекста.

  4. Сохранить изменения.

Подход Database-First

Подход Database-First, появившийся вместе c Entity Framework, позволяет писать приложения для существующих баз данных. Базы данных в реальных приложениях довольно быстро становятся сложными и пытаться создать модель для существующей базы данных, которую могут понять разработчики, довольно трудно. Еще тяжелее написать код использования модели, в котором происходит взаимодействие с базой данных. Во многих отношениях, подход Database-First является противоположностью подходу Model-First. При подходе Database-First база данных уже существует, поэтому разработчик должен знать, где расположена база данных, а также иметь информацию об имени базы данных. Тем не менее, разработчик не должен понимать внутреннюю работу базы данных - Entity Framework по-прежнему скрывает внутреннюю реализацию из поля зрения.

При этом подходе, рабочий процесс создания модели начинается с создания и проектирования базы данных. После генерации сущностных классов модели из существующей базы данных, работа с Entity Framework аналогична подходам Code-First и Model-First. Это означает создание объекта класса контекста и использование этого объекта для выполнения необходимых задач.

Совместимые с Entity Framework поставщики данных

Для того, чтобы получить доступ к базе данных с помощью Entity Framework, нужно использовать поставщики данных, совместимые с Entity Framework. Поставщики данных (data providers) организуют взаимодействие между сущностными классами и системой управления базами данных (СУБД). Фактически они отвечают за то, например, какой код C# нужно сгенерировать из базы данных при использовании подхода Database-First, или какой код SQL нужно создать, при отображении графической модели EDMX на базу данных.

Visual Studio по умолчанию поставляется поставщиком данных SqlClient, что позволяет получить доступ к большинству версий СУБД SQL Server: 2005, 2008, 2010, 2012, 2014. Начиная с версии Visual Studio 2010, Microsoft отказалась от поддержки SQL Server 2000. Можно также создать приложение, обращающееся к SQL Server Compact. Тем не менее, этот провайдер имеет некоторые строгие ограничения, такие как неспособность поддерживать схемы с одинаковыми именами ограничений.

Вы также можете получить доступ к ряду сторонних поставщиков данных для других СУБД. В настоящее время поставщики данных Entity Framework поддерживаются следующими СУБД: MySQL, Oracle, Progress, VistaDB, Devart, OpenLink, SQL Anywhere, Sybase, SQLite, Synergex, Firebird и PostgreSQL (через поставщик Npgsql).

В списке провайдеров отсутствует поддержка базы данных Access Microsoft. Также Entity Framework не поддерживает старые технологии и методы доступа, такие как Open Database Connectivity (ODBC). Для того, чтобы получить поддержку Entity Framework для конкретной базы данных, вы можете создать EF-совместимый провайдер для нее. Более подробно об этом можно прочитать в статье "EF5 Sample Provider".

Как выбрать нужный подход?

Данный вопрос задает себе каждый разработчик, который планирует работать с Entity Framework. В данном случае можно посоветовать придерживаться целей каждого из подходов. Например, если вы запускаете приложение с нуля и у вас нет базы данных, то удобнее использовать подход Model-First. Если база данных есть, то можно использовать Database-First. Если нужно добавить поддержку Entity Framework в уже существующее приложение, где определена модель данных, логичнее всего использовать подход Code-First.

Однако, можно посоветовать использовать подход, удобный для разработчика. Очевидно, что подход Database-First удобен для разработчиков, которые хорошо разбираются в проектировании баз данных и знают основы T-SQL, т.к. этот подход подразумевает создание базы данных вручную. Model-First больше подходит для архитекторов приложений, т.к. использует удобную графическую среду и абстрагируется от реализации базы данных и создания классов модели. Code-First более удобен для программистов C#, т.к. позволяет настраивать детали базы данных из кода.

В следующей таблице показана сводка различных подходов для работы с Entity Framework:

Типы подходов для работы с Entity Framework
Использование БД Ориентация подхода Подход Описание
Новая БД На графическую модель Model-First

Если вам необходимо создать новую базу данных и вы хотите увидеть дизайн базы в графическом виде, подход Model-First работает лучше всего. Model-First использует следующий рабочий процесс:

  • Вы можете создать модель, используя графический конструктор EDMX.

  • Вы генерируете базу данных на основе этой модели.

  • Entity Framework автоматически генерирует классы, необходимые для взаимодействия с базой данных.

Существующая БД На графическую модель Database-First

Если у вас уже есть база данных и вы хотите манипулировать ею используя графический редактор, то подход Database-First работает лучше всего. Database-First использует следующий рабочий процесс:

  • Вы генерируете модель EDMX из существующей базы данных.

  • Entity Framework автоматически генерирует классы, необходимые для взаимодействия с базой данных.

Новая БД На код Code-First

Если вам необходимо создать новую базу данных и вы предпочитаете работать с кодом, то лучшим подходом будет Code-First, использующий следующий рабочий процесс:

  • Вы вручную создаете классы, которые определяют данные в каждой таблице базы данных.

  • Вы определяете отношения между таблицами с помощью различных атрибутов и виртуальных методов.

  • При необходимости, вы также настраиваете детали подключения (например, строку подключения).

  • Entity Framework автоматически формирует базу данных во время выполнения.

Существующая БД На код Code-First (Code-Second)

Если для существующей базы данных вы хотите вручную создать модель в коде, то нужно использовать подход Code-First, который некоторые разработчики также называют Code-Second, т.к. он применяется к уже существующей базе данных. Рабочий процесс выглядит следующим образом:

  • Вы перепроектируете классы, которые определяют данные для каждой таблицы в базе данных с помощью кода.

  • Вы отображаете отношения между таблицами в базе данных на код модели.

Пройди тесты
Лучший чат для C# программистов