Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
После добавления миграций их необходимо развернуть и применить к базам данных. Существуют различные стратегии для этого, с некоторыми более подходящими для рабочих сред и других для жизненного цикла разработки.
Note
Независимо от стратегии развертывания всегда проверяйте созданные миграции и тестируйте их перед применением к рабочей базе данных. Миграция может удалить столбец, когда его намеревались переименовать, или может по различным причинам завершиться сбоем при применении к базе данных.
Скрипты SQL
Рекомендуемый способ развертывания миграции в рабочую базу данных — создание скриптов SQL. К преимуществам этой стратегии относятся следующие преимущества:
- Скрипты SQL можно проверить для точности; Это важно, так как применение изменений схемы к рабочим базам данных является потенциально опасной операцией, которая может привести к потере данных.
- В некоторых случаях скрипты можно настроить в соответствии с конкретными потребностями рабочей базы данных.
- Скрипты SQL можно использовать в сочетании с технологией развертывания и даже создавать в рамках процесса CI.
- Скрипты SQL можно предоставлять в DBA и управлять и архивировать отдельно.
Базовое использование
Ниже представлен процесс создания SQL-скрипта из пустой базы данных до последней миграции:
dotnet ef migrations script
Из (в подразумевающееся)
В следующем примере создается скрипт SQL из данной миграции в последнюю миграцию.
dotnet ef migrations script AddNewTables
С "От" и "До"
В следующем примере создается скрипт SQL из указанной from миграции на указанную to миграцию.
dotnet ef migrations script AddNewTables AddAuditTable
Для генерации сценария отката можно использовать более новую версию from, чем to.
Warning
Обязательно учитывайте возможные сценарии потери данных.
Создание скрипта принимает следующие два аргумента, чтобы указать, какой диапазон миграций следует создать:
- Миграция from должна быть последней миграцией, применяемой к базе данных перед выполнением скрипта. Если не было применено ни одной миграции, укажите
0(это значение по умолчанию). - Миграция to является последней миграцией, применяемой к базе данных после выполнения скрипта. По умолчанию она является последней миграцией в проекте.
Скрипты Idempotent SQL
Скрипты SQL, созданные выше, можно применять только для изменения схемы с одной миграции на другую; Вы несете ответственность за применение скрипта соответствующим образом и только к базам данных в правильном состоянии миграции. EF Core также поддерживает создание идемпотентных скриптов, которые внутренне проверяют, какие миграции уже применены (через таблицу журнала миграций) и применяются только отсутствующие. Это полезно, если вы не знаете, какая последняя миграция применена к базе данных, или если вы развертываете на нескольких базах данных, каждая из которых может находиться на разной стадии миграции.
Ниже приводится идемпотентная миграция:
dotnet ef migrations script --idempotent
Программы командной строки
Средства командной строки EF можно использовать для применения миграций к базе данных. Хотя этот подход полезен для локальной разработки и тестирования миграций, он не подходит идеально для управления рабочими базами данных.
- Команды SQL применяются непосредственно средством, не предоставляя разработчику возможность проверять или изменять их. Это может быть опасно в рабочей среде.
- Пакет SDK .NET и средство EF должны быть установлены на рабочих серверах и требуют исходного кода проекта.
Последующие действия обновят вашу базу данных до последней миграции:
dotnet ef database update
Обновления, которые приведут вашу базу данных к указанной миграции:
dotnet ef database update AddNewTables
Обратите внимание, что это можно использовать для отката к более ранней миграции.
Warning
Обязательно учитывайте возможные сценарии потери данных.
Дополнительные сведения о применении миграций при помощи инструментов командной строки см. в справочнике по средствам EF Core.
Bundles
Пакеты миграции — это исполняемые файлы, представленные в виде одного файла, которые можно использовать для применения миграций к базе данных. Они устраняют некоторые недостатки скрипта SQL и средств командной строки:
- Выполнение скриптов SQL требует дополнительных средств.
- Обработка транзакций и поведение при ошибках этих средств являются неустойчивыми и иногда неожиданными. Это может оставить вашу базу данных в неопределённом состоянии, если при применении миграций происходит сбой.
- Пакеты можно создавать в рамках процесса CI и легко выполнять позже в процессе развертывания.
- Пакеты могут выполняться без установки пакета SDK .NET или средства EF (или даже среды выполнения .NET при автономном использовании) и не требуют исходного кода проекта.
Следующее генерирует пакет:
dotnet ef migrations bundle
Ниже приводится создание автономного пакета для Linux:
dotnet ef migrations bundle --self-contained -r linux-x64
Дополнительные сведения о создании пакетов см. в разделе справочник по инструментам EF Core.
efbundle
Результирующий исполняемый файл по умолчанию называется efbundle . Его можно использовать для обновления базы данных до последней миграции. Это равносильно запуску dotnet ef database update или Update-Database.
Arguments:
| Argument | Description |
|---|---|
<MIGRATION> |
Целевая миграция. Если значение "0", все миграции будут отменены. По умолчанию используется последняя миграция. |
Options:
| Option | Short | Description |
|---|---|---|
--connection <CONNECTION> |
Строка подключения к базе данных. Значение по умолчанию используется, как указано в AddDbContext или OnConfiguring. | |
--verbose |
-v |
Отображение подробных выходных данных. |
--no-color |
Не цветируйте выходные данные. | |
--prefix-output |
Выходные данные с добавлением префикса уровня. |
В следующем примере применяется миграция к локальному экземпляру SQL Server с использованием указанного имени пользователя и учетных данных:
.\efbundle.exe --connection 'Data Source=(local)\MSSQLSERVER;Initial Catalog=Blogging;User ID=myUsername;Password={;'$Credential;'here'}'
Warning
Не забудьте скопировать appsettings.json вместе с пакетом. Пакет требует наличия файла appsettings.json в каталоге выполнения.
Пример пакета миграции
Пакет должен включать в себя миграции. Они создаются с помощью dotnet ef migrations add, как описано в "Создание первой миграции". После того как ваши миграции будут готовы к развертыванию, используйте dotnet ef migrations bundle для создания пакета. Рассмотрим пример.
PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations bundle
Build started...
Build succeeded.
Building bundle...
Done. Migrations Bundle: C:\local\AllTogetherNow\SixOh\efbundle.exe
PS C:\local\AllTogetherNow\SixOh>
Выходные данные представляют собой исполняемый файл, подходящий для целевой операционной системы. В моем случае это Windows x64, поэтому я получаю efbundle.exe, который размещается в мою локальную папку. При выполнении этого исполняемого файла применяются содержащиеся в нем миграции:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
Applying migration '20210903083845_MyMigration'.
Done.
PS C:\local\AllTogetherNow\SixOh>
Как и в случае с dotnet ef database update или Update-Database, миграции применяются к базе данных только в том случае, если они еще не были применены. Например, при повторном выполнении одного и того же пакета ничего не происходит, так как нет новых миграций для применения.
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
No migrations were applied. The database is already up to date.
Done.
PS C:\local\AllTogetherNow\SixOh>
Однако если в модель были внесены изменения, и с помощью dotnet ef migrations add созданы дополнительные миграции, они могут быть объединены в новый исполняемый файл и готовы к применению. Рассмотрим пример.
PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations add SecondMigration
Build started...
Build succeeded.
Done. To undo this action, use 'ef migrations remove'
PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations add Number3
Build started...
Build succeeded.
Done. To undo this action, use 'ef migrations remove'
PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations bundle --force
Build started...
Build succeeded.
Building bundle...
Done. Migrations Bundle: C:\local\AllTogetherNow\SixOh\efbundle.exe
PS C:\local\AllTogetherNow\SixOh>
Tip
Этот --force параметр можно использовать для перезаписи существующего пакета новым.
При выполнении этого нового пакета к базе данных применяются следующие две новые миграции:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
Applying migration '20210903084526_SecondMigration'.
Applying migration '20210903084538_Number3'.
Done.
PS C:\local\AllTogetherNow\SixOh>
По умолчанию пакет использует строку подключения к базе данных из конфигурации приложения. Однако можно перенести другую базу данных, передав строка подключения в командной строке. Рассмотрим пример.
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe --connection "Data Source=(LocalDb)\MSSQLLocalDB;Database=SixOhProduction"
Applying migration '20210903083845_MyMigration'.
Applying migration '20210903084526_SecondMigration'.
Applying migration '20210903084538_Number3'.
Done.
PS C:\local\AllTogetherNow\SixOh>
Note
На этот раз все три миграции были применены, так как ни одна из них еще не была применена к рабочей базе данных.
Применить миграции в режиме выполнения
Приложение может применять миграции программным способом, как правило, во время запуска. Несмотря на производительность локальной разработки и тестирования миграций, этот подход не подходит для управления рабочими базами данных по следующим причинам:
- Для версий EF до 9, если запущено несколько экземпляров приложения, оба приложения могут попытаться применить миграцию одновременно и завершиться сбоем (или хуже, привести к повреждению данных).
- Аналогичным образом, если приложение обращается к базе данных во время миграции другого приложения, это может привести к серьезным проблемам.
- Приложение должно иметь повышенный доступ для изменения схемы базы данных. Обычно рекомендуется ограничить разрешения базы данных приложения в рабочей среде.
- Важно иметь возможность отката примененной миграции в случае возникновения проблемы. Другие стратегии предоставляют это легко и без дополнительных настроек.
- Команды SQL применяются непосредственно программой, не предоставляя разработчику возможность проверять или изменять их. Это может быть опасно в рабочей среде.
Чтобы применить миграции программным способом, вызовите context.Database.MigrateAsync(). Например, обычное приложение ASP.NET может выполнять следующие действия:
public static async Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
await db.Database.MigrateAsync();
}
host.Run();
}
Обратите внимание, что MigrateAsync() строится на основе IMigrator службы, которая может использоваться для более сложных сценариев. Для доступа к нему используйте myDbContext.GetInfrastructure().GetService<IMigrator>().
Warning
- Тщательно рассмотрите возможность использования этого подхода в рабочей среде. Опыт показал, что простота этой стратегии развертывания перевешивает создаваемые проблемы. Вместо этого рекомендуется создавать скрипты SQL из миграций.
- Не вызывайте
EnsureCreatedAsync()передMigrateAsync().EnsureCreatedAsync()обходит миграции для создания схемы, что приводит к сбоюMigrateAsync().
Блокировка миграции
Начиная с EF Core 9, MigrateAsync и Migrate автоматически приобретают блокировку на уровне базы данных перед применением любых миграций. Это защищает от повреждения базы данных, которая может привести к параллельному выполнению нескольких экземпляров приложений, что является общим сценарием при применении миграций во время выполнения. Блокировка удерживается на время выполнения миграции, включая любой инициализационный код, и автоматически освобождается после завершения операции.
Блокировка миграции применяется при применении миграции с помощью любого из следующих методов:
-
dotnet ef database update(CLI .NET) -
Update-Database(консоль диспетчер пакетов) - Пакеты миграции
- MigrateAsync и Migrate (миграция среды выполнения)
Сценарии SQL не влияют на блокировку миграции, так как они применяются за пределами EF Core.
Warning
Механизм блокировки значительно зависит от поставщиков баз данных и может включать проблемы, связанные с поставщиком. Например, поставщик SQLite использует таблицу блокировки, которая может стать заброшенной, если процесс завершается неожиданно. Всегда обратитесь к документации поставщика по подробным сведениям.
Ограничения
- Упаковка MigrateAsync в явную транзакцию не поддерживается. Дополнительные сведения см. в разделе Исключение выбрасывается при применении миграций в явной транзакции.
- В SQLite заброшенные блокировки миграции могут блокировать последующие миграции.