← Назад к вопросам

Что такое миграция?

1.8 Middle🔥 212 комментариев
#Entity Framework и ORM#Базы данных и SQL

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое миграция в разработке?

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

В контексте C# и .NET, миграции обычно реализуются через ORM (Object-Relational Mapping) библиотеки, такие как Entity Framework Core (EF Core). Они позволяют синхронизировать модель данных в коде (классы-сущности) с реальной схемой базы данных, минимизируя ручную работу и предотвращая ошибки.

Основные принципы миграций:

  1. Версионирование: Каждая миграция представляет отдельный шаг изменения и имеет уникальное имя/идентификатор. Это создает историю изменений базы данных.
  2. Автоматизация: Миграции генерируются на основе изменений в модели данных (классах DbContext и сущностях) или создаются ручными скриптами, а затем применяются инструментами (CLI, PMC).
  3. Отслеживание состояния: ORM хранит информацию о примененных миграциях (обычно в специальной таблице, например, __EFMigrationsHistory), чтобы знать, какие изменения уже внесены в базу.
  4. Обратимость (вверх и вниз): Миграция содержит два основных скрипта:
    *   **Up** (`Up()` метод) — применяет изменение (например, создает таблицу).
    *   **Down** (`Down()` метод — откатывает изменение (например, удаляет таблицу). Это позволяет вернуться к предыдущему состоянию.

Работа с миграциями в Entity Framework Core:

Процесс обычно включает следующие шаги:

1. Создание (генерация) миграции После изменения модели данных (например, добавления нового свойства в класс сущности) вы создаете миграцию с помощью команд. EF Core сравнивает текущую модель с предыдущим состоянием и генерирует код миграции.

# Команда в .NET CLI (или Package Manager Console в Visual Studio)
dotnet ef migrations add AddProductDescriptionColumn

Это создает новый класс миграции в проекте:

// Файл миграции: 20240510_120000_AddProductDescriptionColumn.cs
public partial class AddProductDescriptionColumn : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AddColumn<string>(
            name: "Description",
            table: "Products",
            type: "nvarchar(500)",
            maxLength: 500,
            nullable: true);
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropColumn(
            name: "Description",
            table: "Products");
    }
}

2. Применение миграции к базе данных Созданная миграция применяется к целевой базе данных, физически изменяя ее схему.

# Применение всех непримененных миграций
dotnet ef database update

# Применение до конкретной миграции
dotnet ef database update AddProductDescriptionColumn

# Откат до предыдущей миграции (используя Down метод)
dotnet ef database update PreviousMigrationName

3. Скрипт миграции для CI/CD Для производственных сред часто создается отдельный SQL-скрипт, который можно включить в процесс непрерывной интеграции.

# Генерация SQL скрипта для всех миграций или диапазона
dotnet ef migrations script --output migration.sql

Преимущества использования миграций:

  • Согласованность: Гарантирует, что схема базы данных во всех окружениях (разработка, тестирование, production) идентична и соответствует коду.
  • История изменений: Позволяет видеть всю эволюцию базы данных в коде.
  • Безопасность: Изменения выполняются через контролируемые скрипты, снижается риск человеческой ошибки при прямом SQL-редактировании.
  • Совместная работа: Миграции в системе контроля версий (Git) позволяют команде работать синхронно.
  • Откат изменений: Возможность вернуться к предыдущей версии схемы при возникновении проблем.

Типы миграций:

  • Автоматические/Code-first: Генерируются ORM на основе изменений в классах-моделях (как показано выше с EF Core).
  • Ручные/script-based: Разработчик самостоятельно пишет SQL или код миграции для сложных изменений, которые ORM не может корректно выразить (например, перенос данных между таблицами, сложные индексы).

Ключевые таблицы и инструменты:

  • Таблица истории миграций (__EFMigrationsHistory): EF Core автоматически создает и поддерживает эту таблицу, хранящую названия примененных миграций.
  • DbContext: Контекст базы данных, который содержит модель и используется для генерации миграций.
  • Инструменты CLI (dotnet ef): Основной инструмент для управления миграциями в .NET Core/5/6+.

Пример более сложной миграции:

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

public partial class SplitUserNameIntoFirstAndLast : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        // 1. Добавляем новые колонки
        migrationBuilder.AddColumn<string>(
            name: "FirstName",
            table: "Users",
            maxLength: 100,
            nullable: false,
            defaultValue: "");
        migrationBuilder.AddColumn<string>(
            name: "LastName",
            table: "Users",
            maxLength: 100,
            nullable: false,
            defaultValue: "");

        // 2. Переносим данные из старой колонки FullName в новые (пример логики)
        migrationBuilder.Sql(@"
            UPDATE Users
            SET FirstName = SUBSTRING(FullName, 1, CHARINDEX(' ', FullName) - 1),
                LastName = SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))
            WHERE FullName IS NOT NULL AND CHARINDEX(' ', FullName) > 0;
        ");

        // 3. Удаляем старую колонку
        migrationBuilder.DropColumn(
            name: "FullName",
            table: "Users");
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        // Операции отката в обратном порядке
        migrationBuilder.AddColumn<string>(
            name: "FullName",
            table: "Users",
            maxLength: 200,
            nullable: true);

        migrationBuilder.Sql(@"
            UPDATE Users
            SET FullName = FirstName + ' ' + LastName;
        ");

        migrationBuilder.DropColumn(
            name: "FirstName",
            table: "Users");
        migrationBuilder.DropColumn(
            name: "LastName",
            table: "Users");
    }
}

Таким образом, миграции — это критически важный механизм для современной разработки, который обеспечивает надежное, контролируемое и повторяемое управление эволюцией схемы базы данных вместе с развитием приложения. В C# backend с использованием Entity Framework Core этот процесс глубоко интегрирован в инструментарий и является стандартной практикой.