运行中 MigrateAsync() 启动时? 您正在给您的应用程序数据库所有者权利, 希望不会出任何差错。 有一个更好的方法 — EF 迁移捆让您将迁移作为受控的 CI 步骤, 保护您的生产应用程序的安全 。 但问题是: 有时“ 错误” 方式其实是好的。 我们来探索何时使用每种方法 。
此博客使用 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;只有在部署期间才使用 CID 跑者注: 用于生产级安保,使用 管理身份 而不是连接字符串。 但捆绑仍然是从跑步移民中迈出的一大步。
- 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前测试, DBA 上交( 独立前端, 不需要 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
Catchs 语法错误、违反限制、FK问题 -- -- 所有 之前 CI或生产。
捆包的代代慢慢 - 30+秒的大型项目,不要在每一个建筑上产生。
如果您真的想要自动生成, 请添加一个 MSBulild 目标 :
<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 脚本上的公务 docs.
- 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
发发援援协调会 是 基于状态的 否 以移徙为基础的移徙人口。您根据目标数据库定义想要的图案, SqlPackage diffs 。
SqlPackage.exe /Action:Publish /SourceFile:MyDatabase.dacpac /TargetConnectionString:"..."
专业: Schema作为代码、自动生成、处理一切(表格、视图、SP、索引)、企业工具。
关节 : 仅 SQL 服务器, 两个地方的图案( EF 模型 + SQL 项目) , diff 引擎的选择有问题, 列重命名看起来像 drop+add 。
见见 Sql 软件包文档.
最佳办法 需要 .NET 自动追踪 应用 .DBA 友好 . .
|----------|----------|---------------|---------------------|--------------|-------------------|
| MigrateAsync() * 发展/小型项目 * * 是(临时) * * 是 * 否 * * 是 * * * 是 * * * 是
--idempotent 是的,是的,是的,是的,是的。
DACPAC SQL 服务器企业移民在当地工作,但不在移民中心工作? 检查您所执行的两个文件 :
20231115_AddUserTable.cs - 移徙法20231115_AddUserTable.Designer.cs - 模型快照缺少设计器文件 = 沉默失败 。
dotnet ef migrations bundle --context BlogDbContext --output blog-migrations.exe
dotnet ef migrations bundle --context IdentityDbContext --output identity-migrations.exe
--connection 参数参数appsettings.json在 CI 中使用环境变量。
EF 工具需要对 DbContext 进行即时化 DbContext 。如果您的 DbCtext 在一个单独的项目中,或者启动过程复杂,请执行 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"吗?上面写着, 但短版本是: 捆包是便携式的手工艺品。 您的部署步骤不需要 EF CLI 、 源代码或设计时间分辨率 。 同样的捆包在测试、 中转和测试中运行 - 零漂移 。
如果你是独唱,数据是公开的 爆炸半径低 MigrateAsync() 。但当您添加第二个开发者、敏感数据或多个环境时,捆包会为自己付费。
EF不自动回滚。 选项 :
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 完成 。
EF捆绑是EF本地的解决方案,但是 流流者 和 弹顶 关键区别是:这些是针对移民的工具,而EF包来自您现有的EF模式。
使用使用 --idempotent 脚本 :
dotnet ef migrations script --idempotent --output migrations.sql
DBA审查和批准。
这是一个部署战略问题,不是移民问题。
套装不能解决问题 只会让第三步更可预测
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.