Працює MigrateAsync() Під час запуску? Ви надаєте вашим програмам права власника бази даних і сподіваєтеся, що нічого не станеться. Є кращий спосіб - Міграції EC дозволяють вам запускати міграцію як контрольований крок CI, утримуючи ваш комп' ютерний додаток. Але ось дещо: іноді " wrong " насправді непоганий. Давайте розглянемо, коли слід використовувати кожен підхід.
Офіційні документи: Огляд міграцій | Як застосовувати міграцію | БундлесCity in New Jersey USA
Цей блог використовує MigrateAsync() ось чому це добре для мене і чому це можливо не для тебе.
В моєму Program.cs У мене є файл:
using (var scope = app.Services.CreateScope())
{
var blogContext = scope.ServiceProvider.GetRequiredService<IMostlylucidDBContext>();
await blogContext.Database.MigrateAsync();
}
MigrateAsync() застосувати пересилання з черги і за потреби створити базу даних. Просте, але проблема:
db_owner Ты только что дал своему программу ключи, чтобы бросить столы.Чому мені це не вдається: публічні дані, єдина мережа Докера, персональний проект. Ти, мабуть, не можеш.
Смуга EF - це самодостатній виконуваний файл, у якому містяться ваші компіляції. Думайте про те, що dotnet ef database update пакунок у окремому місці .exe.
Чому перемагають пучки:
db_owner; Робить лише інструмент запуску CI, лише під час виконанняПримітка: Для безпеки виробництва, використовуйте Керований профіль Але снопи все - таки є основним кроком до перельоту через бігові перельоти.
- name: Install EF Core tools
run: dotnet tool install --global dotnet-ef
- name: Add EF tools to PATH
run: echo "$HOME/.dotnet/tools" >> $GITHUB_PATH
- name: Generate EF migration bundle
run: |
dotnet ef migrations bundle \
--project ${{ env.WEB_PROJECT }} \
--output efbundle.exe \
--configuration ${{ env.BUILD_CONFIGURATION }} \
--runtime ${{ env.RUNTIME_IDENTIFIER }} \
--context AdminDbContext \
env:
AdminSite__ConnectionString: ${{ secrets.PROD_SQL_CONNECTIONSTRING }}
- name: Run EF migration bundle
run: |
./efbundle.exe
env:
AdminSite__ConnectionString: ${{ secrets.PROD_SQL_CONNECTIONSTRING }}
П' ятчик читає рядки з' єднання зі змінних середовища і застосовує перельоти з черги. Вже застосовано? Він просто успішно завершує роботу.
Без CI? не хочете перевірити перед тим, як натискати? Зберіть вузли локально.
Випадки використання: Тестування перед CI, DBA whichoff (вбудований приклад, без використання SDK), блокування, усування вад з --verbose.
# Install EF CLI (once)
dotnet tool install --global dotnet-ef
# Basic bundle
dotnet ef migrations bundle \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid \
--output efbundle.exe
# Self-contained (includes runtime - portable to machines without .NET)
dotnet ef migrations bundle \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid \
--output efbundle.exe \
--self-contained
# Cross-platform (e.g., build on Windows, deploy to Linux)
dotnet ef migrations bundle \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid \
--output efbundle \
--runtime linux-x64
# Using default connection string from appsettings.json
./efbundle.exe
# Override with a specific connection string
./efbundle.exe --connection "Host=localhost;Database=mostlylucid;Username=postgres;Password=secret"
# Using an environment variable (matches your config key)
$env:ConnectionStrings__DefaultConnection="Host=localhost;..." # PowerShell
export ConnectionStrings__DefaultConnection="Host=localhost;..." # Bash
./efbundle.exe
# See what migrations would be applied without running them
./efbundle.exe --dry-run
# Verbose output for debugging
./efbundle.exe --verbose
# Apply migrations up to a specific migration (useful for testing)
./efbundle.exe --target-migration "20231115_AddUserTable"
# Combine options
./efbundle.exe --verbose --dry-run
# 1. Create migration
dotnet ef migrations add AddNewFeature \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid
# 2. Build bundle
dotnet ef migrations bundle \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid \
--output efbundle.exe
# 3. Dry run first
./efbundle.exe --dry-run --verbose
# 4. Run for real
./efbundle.exe --verbose
# 5. Broken? Remove and retry
dotnet ef migrations remove \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid
Перехоплює синтаксичні помилки, обмеження, проблеми з FK - all до СІ або виробництво.
Покоління бундлів є повільним - 30+секунд на великих проектах.
Якщо ви справді бажаєте автоматичного створення, додайте ціль MSBuild:
<Target Name="BuildMigrationBundle">
<Exec Command="dotnet ef migrations bundle --output $(OutputPath)efbundle.exe --force" />
</Target>
Тоді: dotnet build -t:BuildMigrationBundle
Найкращі з обох світів: зручність на місці, безпека у виробництві.
if (builder.Environment.IsDevelopment())
{
using var scope = app.Services.CreateScope();
var context = scope.ServiceProvider.GetRequiredService<IMostlylucidDBContext>();
await context.Database.MigrateAsync();
}
// Production: CI pipeline runs the bundle
Створює простий SQL замість виконуваного файла. Чудово для аналізу DBA і існуючих процесів керування змінами.
# All migrations
dotnet ef migrations script --output migrations.sql
# Idempotent (safe to run multiple times) - USE THIS
dotnet ef migrations script --idempotent --output migrations.sql
# Range of migrations
dotnet ef migrations script FromMigration ToMigration --output migrations.sql
Прос: Повна видимість, будь-який клієнт SQL може запустити цю програму, дружній до версій керування версіями, програма у схваленні DBA.
Збори: Без автодосліджень (корисно) --idempotent), ручне виконання, потенційне дрейфування, якщо ви змінюєте скрипти.
Див. офіційні документи скриптів SQL.
- name: Generate and apply migrations
run: |
dotnet ef migrations script --idempotent --output migrations.sql
# SQL Server
sqlcmd -S ${{ secrets.DB_SERVER }} -d ${{ secrets.DB_NAME }} -i migrations.sql
# Or PostgreSQL
PGPASSWORD=${{ secrets.DB_PASSWORD }} psql -h ${{ secrets.DB_HOST }} -f migrations.sql
DACPACs є заснований на станах неDescription of a condition. Do not translate key words (# V1S #, # V1 #,) заснований на міграціях. Ви визначаєте бажану схему, а SqlPackage розшифрує її у базі даних призначення.
SqlPackage.exe /Action:Publish /SourceFile:MyDatabase.dacpac /TargetConnectionString:"..."
Прос: Схема як код, автоматичне створення різниці, керування всім (таблями, переглядами, SP, індексами), інструментами для роботи з підприємцями.
Збори: Тільки сервер SQL, схема у двох місцях (EF Modes + SQL project), рушій різниці робить сумнівний вибір, перейменування стовпчиків виглядає як floop+add.
Див. Документи SqlPackage.
Д'Ап-доріжка Ап-пайлі ДБА ДБО ДБІ ДБ
|----------|----------|---------------|---------------------|--------------|-------------------|
| MigrateAsync() Д_ д. д. д. д. д. д. д. д. д. д. д. д. д.
Д-р Харріс:
♪SQ ZOGE-DBA керується середовищами ♪ Ні' з --idempotent Д. Так.
*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Міграції працюють у вашій місцевості, але не на ЦРУ? Перевірте, чи передано обидва файли:
20231115_AddUserTable.cs - Код міграцій20231115_AddUserTable.Designer.cs - Знімок моделіВідсутній файл Designer = безмовна помилка.
dotnet ef migrations bundle --context BlogDbContext --output blog-migrations.exe
dotnet ef migrations bundle --context IdentityDbContext --output identity-migrations.exe
--connection аргументappsettings.jsonВикористовувати змінні середовища у CI.
EC- інструменти повинні миттєво втілювати ваш DbContext. Якщо ваш DbContext знаходиться у окремому проекті або має складний запуск, реалізацію IDesignTimeDbContextFactory<T>:
public class AdminDbContextFactory : IDesignTimeDbContextFactory<AdminDbContext>
{
public AdminDbContext CreateDbContext(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true)
.AddEnvironmentVariables()
.AddUserSecrets<AdminDbContextFactory>()
.Build();
var connectionString = config["AdminSite:ConnectionString"]
?? throw new InvalidOperationException("Missing connection string");
var optionsBuilder = new DbContextOptionsBuilder<AdminDbContext>();
optionsBuilder.UseSqlServer(connectionString, sql => sql.CommandTimeout(120));
return new AdminDbContext(optionsBuilder.Options);
}
}
Використовувати, якщо: DbContext у окремому проекті, комплексному запуску, потрібні таємниці користувача для дизайну.
Звичайні питання і відштовхування, які я отримав.
dotnet ef database update У CI? "Наведена вище, але коротка версія: пучки - це портативні артефакти. Ваш крок впровадження не потребує EC CLI, вихідного коду або роздільної здатності у режимі дизайну. Такий же вузол працює у тестах, застійах і прод - нуль дрейфів.
Можливо. а радіус вибуху низький - MigrateAsync() Але як тільки ви додаєте ще один розробник, чутливі дані або багато середовищ, снопи платять самі за себе.
EC не виконує автоматичних розкладок. Параметри:
Down() міграція і запуск (але вам слід записати її)Для критичних систем: спочатку тест перелітає на клон бази даних.
Так. Контейнер " Бондле + init " є суцільним шаблоном:
initContainers:
- name: migrate
image: myapp:latest
command: ["./efbundle.exe"]
env:
- name: ConnectionStrings__Default
valueFrom:
secretKeyRef:
name: db-secrets
key: connection-string
Контейнер App чекає на завершення init.
Вони працюють чудово. Смуги ЄФ є еФ-нативним рішенням, але FluentMigrator і DbUp Ключова відмінність: ці інструменти є специфічними для міграцій, в той час як EF-групи походять від вашої EC-моделі.
Користування --idempotent скрипти:
dotnet ef migrations script --idempotent --output migrations.sql
DBA рецензування і схвалення.
Це питання стратегії розповсюдження, а не питання міграції.
Бонделі не вирішують це - вони просто роблять крок 3 більш передбачуваним.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.