Данная статья не является инструкцией по работе с EF миграциями. Здесь не будет инфы о том, как их создавать. Здесь я собрал несколько скользких моментов и попытки их обойти. Давайте начнем!

Старт миграций при запуске приложения

Вам знаком следующий код?

context.Database.Migrate();

Если да, вероятнее всего вы накатываете миграции автоматически при старте проекта. Плохо это или хорошо, можете обсудить в комментариях. Я же в свою очередь хочу предостеречь вот от чего.

Когда вы в cmd, PS или в консоли диспетчера пакетов вызываете какую либо операцию, связанную с миграциями, эта операция включает в явном или неявном виде 2 параметра: проект и запускаемый проект. Проект - это сборка, в которую в конечном счете будут помещены миграции. А вот запускаемый проект - проект, выбранный запускаемым для данного решения (sln). При работе через консоль диспетчера пакетов вы этот параметр никогда не увидите.

Что это означает? А то, что ваш запускаемый проект при выполнении операции с миграциями будет собран (ну об этом вы знаете) и запущен. А это, в свою очередь, означает, что помимо всяких интеграционных штук, которые неожиданно для вас могут отработать, выполнение может дойти до кода, приведенного выше. К чему это может привести? К тому, что текущая операция с миграциями накатит предыдущую созданную вами миграцию. То есть, вы создаете миграцию, тут же, замечаете, что допустили ошибку в настройке сущности, пытаетесь ее удалить через Remove-Migration, но получаете от ворот поворот, потому что в момент запуска операции удаления миграции, она накатывается на базу. Вы, конечно же, выполняете роллбэк последней миграции и затем снова вызываете Remove-Migration. Но, угадайте, что произойдет?

Чтобы это побороть, могу подсказать 2 подхода:

  1. Не использовать применение миграций при запуске проекта

  2. Использовать в качестве запускаемого проекта для операций с миграциями отдельный консольный запускаемый проект.

Если есть идеи лучше, пишите в комментариях. С удовольствием обсужу с вами и приму к сведению.

Удаление миграций

В общем-то, удалять миграции я рекомендую только в двух случаях:

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

  2. Миграция еще не слита в ветку, вы создали ее локально, но она не правильная.

Во втором случае можно удалить последнюю миграцию, использовав команду Remove-Migration. Если миграцию уже применили к базе, надо ее предварительно откатить. После выполнения Remove-Migration почистите мусор в файле проекта (csproj). Так же, если у вас всего одна миграция или несколько, но еще не закоммичены, быстрее будет откатить снапшот через Git (или вашу систему контроля версий) и удалить файлы миграций.

В данном случае универсальным решением будет откатить базу до удаляемой миграции, удалить все миграции после проблемной (вместе с ней). Мусор в csproj файле при этом чистить не надо.

Создание SQL миграций

Возможно, не все знают, но на основе разработческих миграций (тех, что создаются в коде, это майки их где-то так называли) можно создать SQL скрипты. Для этого есть команда Script-Migration. С ее помощью можно создать в т. ч. идемпотентные скрипты.

А начиная с версии EF Core 3.0 появилась команда Script-DbContext для создания миграций из контекста базы.

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

Редактирование сущностей

Нут тут, казалось бы, все просто. Мы меняем что-либо в сущности, создаем миграцию, радуемся результату. Вот только результат может быть неожиданным, когда вам нужно удалить одно поле и создать другое того же типа. Мигратор при этом создаст команду для переименования столбца в БД. Все данные из удаляемого столбца, соответственно, перенесутся в новый. В данном случае можно создать 2 миграции: для удаления столбца и для создания нового. После этого, чтобы не маячили 2 миграции вместо одной, можно совместить их код Up и Down и последнюю удалить.

Заключение

В заключении хочу сказать, будьте внимательны к данным, проверяйте новые миграции, вдумывайтесь в них, не бойтесь их редактировать. А на всякие неочевидные грабли при работе с EF вы все равно наступите.