ABP VNext + FluentMigrator:数据库迁移管理
ABP VNext + FluentMigrator:数据库迁移管理 🚀
📚 目录
- ABP VNext + FluentMigrator:数据库迁移管理 🚀
- 1. 引言
- ✨ TL;DR
- 📚 背景与动机
- 2. 环境与依赖
- 🛠️ 平台版本
- 🔗 核心 NuGet 包
- 📦 附加包
- 3. 初始配置 🛠️
- 3.1 安装 CLI 工具
- 3.2 安装包与服务注册
- 3.3 定义迁移目录结构
- 4. 编写迁移类 ✍️
- 📄 基类与版本号
- 🔑 环境变量注入示例
- 5. 版本管理与回滚 🔄
- 🔄 回滚到指定版本
- ⚙️ 基于标签的回滚
- 6. 与 ABP DbContext 联动 🔗
- 🔄 启动流程
- 7. CI/CD 集成 🚀
- 7.1 本地与流水线脚本
- 7.2 多环境分支与审批
- 8. 错误处理与日志 🐛
- 📋 事务回滚
- 📝 日志配置
- 9. 最佳实践与注意事项 ✔️
1. 引言
✨ TL;DR
- 使用 FluentMigrator 在 ABP VNext 项目中实现代码化、版本化的数据库架构变更 🏗️
- 支持按环境(Development/Staging/Production)执行不同迁移脚本,确保环境一致性 🔄
- 自动化迁移集成到 CI/CD 流程,保证应用的高可用与高一致性 🔧
📚 背景与动机
手动管理 SQL 脚本既容易出错,也难以维护,尤其在多环境部署和团队协作开发时。FluentMigrator 提供了基于 C# 的迁移 API,支持版本控制、回滚和预览功能,能将数据库迁移纳入代码管理,确保迁移的可重复性、可审计性和安全性。结合最新的 ABP VNext 9.x 框架和 .NET 8 LTS,我们可以构建高性能、高可用、可复现的数据库迁移体系。
2. 环境与依赖
🛠️ 平台版本
- .NET 9
- ABP VNext 9.x(模块化项目模板)
🔗 核心 NuGet 包
dotnet add package FluentMigrator.Runner --version 4.1.3
dotnet add package FluentMigrator.Runner.Extensions.ASPNETCore --version 4.1.3
dotnet add package Volo.Abp.EntityFrameworkCore --version 9.0.7
📦 附加包
根据数据库类型,可选:
FluentMigrator.Runner.SqlServer
FluentMigrator.Runner.Postgres
FluentMigrator.Runner.MySql
3. 初始配置 🛠️
3.1 安装 CLI 工具
dotnet tool install --global FluentMigrator.DotNet.Cli --version 4.1.3
dotnet tool restore
3.2 安装包与服务注册
在迁移模块 MyProject.DbMigration/MyDbMigrationModule.cs
中:
public override void ConfigureServices(ServiceConfigurationContext context)
{var configuration = context.Services.GetConfiguration();context.Services.AddFluentMigratorCore().ConfigureRunner(rb => rb.AddSqlServer() // 或 .AddPostgres(), .AddMySql().WithGlobalConnectionString(configuration.GetConnectionString("Default")).ScanIn(typeof(MyDbMigrationModule).Assembly).For.Migrations()).AddLogging(lb => lb.AddFluentMigratorConsole().AddFile("Logs/migration.log"));
}
3.3 定义迁移目录结构
Migrations/├─ 20250101_InitialCreate.cs├─ 20250215_AddCustomerTable.cs└─ Environments/├─ Development/│ └─ 20250301_SeedTestData.cs└─ Production/└─ 20250305_CreateReportingViews.cs
通过目录与命名空间区分环境迁移,便于批量执行或过滤。
4. 编写迁移类 ✍️
📄 基类与版本号
using FluentMigrator;[Migration(20250215)]
public class AddCustomerTable : Migration
{public override void Up() =>Create.Table("Customer").WithColumn("Id").AsGuid().PrimaryKey().WithColumn("Name").AsString(200).NotNullable();public override void Down() =>Delete.Table("Customer");
}
🔑 环境变量注入示例
using FluentMigrator;
using Microsoft.Extensions.Configuration;[Migration(20250301)]
public class SeedTestData : Migration
{private readonly string _env;public SeedTestData(IConfiguration config){_env = config["ASPNETCORE_ENVIRONMENT"];}public override void Up(){if (_env == "Development"){Execute.EmbeddedScript("Migrations.Environments.Development.SeedTestData.sql");}}public override void Down() { /* 可选:清理测试数据 */ }
}
💡 Tips:使用构造函数注入
IConfiguration
,避免在方法中硬编码读取环境变量。
5. 版本管理与回滚 🔄
🔄 回滚到指定版本
runner.MigrateDown(20250101);
⚙️ 基于标签的回滚
在服务注册时添加标签:
.ConfigureRunner(rb => rb.AddSqlServer()….WithTags("Development"))
然后执行仅带该标签的迁移或回滚:
dotnet fm migrate --tags Development
dotnet fm migrate --tags Development --step 2
6. 与 ABP DbContext 联动 🔗
在 ABP 模块的启动阶段自动触发迁移:
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{var runner = context.ServiceProvider.GetRequiredService<IMigrationRunner>();runner.MigrateUp();
}
或者中间件方式:
app.UseFluentMigrator();
🔄 启动流程
7. CI/CD 集成 🚀
7.1 本地与流水线脚本
jobs:migrate:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v3- name: Setup .NETuses: actions/setup-dotnet@v3with:dotnet-version: 8.0.x- name: Restore Toolsrun: dotnet tool restore- name: Restore & Buildrun: dotnet build src/MyProject.DbMigration- name: 预览迁移 SQLrun: dotnet fm migrate --preview \--processor SqlServer \--connection "${{ secrets.DB_CONN }}" \--assembly src/MyProject.DbMigration/bin/Release/net8.0/MyProject.DbMigration.dll- name: 执行 FluentMigrator 迁移run: |dotnet fm migrate \--processor SqlServer \--connection "${{ secrets.DB_CONN }}" \--assembly src/MyProject.DbMigration/bin/Release/net8.0/MyProject.DbMigration.dllif [ $? -ne 0 ]; thenecho "🔴 Migration failed!" exit 1fienv:ASPNETCORE_ENVIRONMENT: ${{ github.ref == 'refs/heads/main' && 'Production' || 'Staging' }}
💡 Tips:使用
--preview
先预览 SQL,再执行;失败时中断流水线并发出通知。
7.2 多环境分支与审批
- 📝
develop
分支自动部署 Dev/Staging - 🔒
main
分支需审批后部署 Production
8. 错误处理与日志 🐛
📋 事务回滚
FluentMigrator 默认支持单个迁移的事务回滚,确保迁移失败时不留半成状态。
📝 日志配置
.AddLogging(lb => lb.AddFluentMigratorConsole().AddFile("Logs/migration.log"));
- 控制台日志:开发调试
- 文件日志:生产环境追踪
建议:结合 Slack/Teams 通知,在流水线失败时自动告警。
9. 最佳实践与注意事项 ✔️
- 💡 命名规范:
YYYYMMDD_描述
保证迁移有序 - ⚠️ 仅管理 Schema:避免在
Up()
写业务逻辑或大量数据 - 🔒 使用 IConfiguration:避免硬编码环境变量,提升灵活性和可测试性
- 🚀 高可用:生产环境可使用分布式锁(如 Redis)避免并发迁移
- 🔄 可复现性:所有迁移脚本纳入版本控制并集成 CI,保证多环境一致