Pull to refresh

Автоматическая миграция БД в Entity Framework

Reading time3 min
Views47K
В процессе разработки ПО, когда ещё не весь функционал определён окончательно, структура БД часто изменяется. И если используется какой-либо ORM-framework, изменение БД после изменения модели данных доставляет некоторые неудобства (по сути нужно проделать двойную работу по изменению класса модели и структуры БД). Вкратце, как сделать миграцию в EF4 Code First с помощью Package Manager Console описано здесь, я же постараюсь описать как работает автоматическая миграция без участия разработчика (точнее, при минимальном участии).


С чего всё началось


Встала задача создания нового проекта, представляющего из себя что-то вроде АРМа.
Посовещавшись, решили использовать Entity Framework Code First, т.к. в перспективе возможна смена СУБД, а с этим вариантом нам нужно будет просто сменить строку соединения (если имеется подходящий ADO.NET провайдер).
Сделали модели данных, класс контекста, наследуемый от DbContext'а:

public class ProjectContext : DbContext
{
    public ProjectContext()
    {
    }

    public ProjectContext(string connString)
        : base(connString)
    {
    }

    public DbSet<Address> Addresses { get; set; }
    ...
}

добавили инициализатор:

public class ProjectInitializer : DropCreateDatabaseIfModelChanges<ProjectContext>
{
    protected override void Seed(ProjectContext context)
    {
         ...
    }
}

и прописываем (в нашем случае в Global.asax) инициализатор:

Database.SetInitializer(new ProjectInitializer());

Всё вроде замечательно, у кого базы нет она создаться, но после уточнения у заказчика деталей, возникла необходимость добавить ещё сущности. А так как разработку ведут несколько разработчиков, произошло массовое пересоздание БД, а данные там уже реальные лежали.

Миграции


Так мы пришли к миграциям. Как советует статья выполнили в Package Manager Console команду:

PM> Add-Migration 1

В проекте появилась папка Migrations, в которой создалось два файла: Configuration.cs, <дата_время>_1.cs. Первый, как следует из названия конфигурация миграции, второй содержит необходимые изменения БД для обновления/отката версии. Далее достаточно выполнить в консоли NuGet'а:

PM> Update-Database

Всё было замечательно, если у кого-то модель не совпадала с БД, он просто делал миграцию в консоли и удалял файлик с миграцией. Пока не пришло время разместить проект на сервере заказчика. NuGet'а там не было, и установить возможности тоже не было (а у хостинг-провайдера такая возможность, отсутствует в принципе, если не берёте сервер).

Автоматическая миграция


Пытаясь выяснить, как делать автоматическую миграцию, вооружившись IntelliSense, методом научного тыка эмпирическим методом выяснили, что нужно сменить класс, от которого наследуется инициализатор:

//public class ProjectInitializer : DropCreateDatabaseIfModelChanges<ProjectContext>
public class ProjectInitializer : MigrateDatabaseToLatestVersion<ProjectContext, Configuration>
{
     ...
}

Запустили и получили такое исключение:



Ага! Делаем, то, что предлагается в сообщении исключения, то есть:

public sealed class Configuration : DbMigrationsConfiguration<ProjectContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

     protected override void Seed(ProjectContext context)
     {
           
     }
}

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



Дело в том, что с точки зрения Entity Framework переименование свойства есть удаление и добавления с новым именем, а таким образом возможно потеря данных. В таких случаях (а их бывает немного), просто нужно создать миграцию вручную командой Add-Migration и поправить вручную DropColumn и CreateColumn на RenameColumn (или ещё что-то, в зависимости от ситуации).

Заключение


На этом всё, надеюсь статья будет полезной. А также надеюсь, что информации от первоисточника по данному вопросу очень мало, потому-что это как-бы бета-версия и с релизом Entity Framework 5.0, не придётся методом проб и ошибок искать правильный вариант использования.
Tags:
Hubs:
+14
Comments22

Articles

Change theme settings