FluentMigrator:如何为同架构多数据库提供迁移支持
在.NET Core 3.1中配置FluentMigrator适配多租户多数据库迁移
1. 安装必要依赖
通过NuGet安装以下包(根据你的数据库类型调整驱动包):
FluentMigrator:核心迁移库FluentMigrator.SqlServer(若用SQL Server,其他数据库替换为对应驱动,如FluentMigrator.MySql)FluentMigrator.DotNet.Cli:可选,用于命令行迁移场景
2. 配置租户数据库连接字符串
在appsettings.json中定义所有租户的连接字符串列表:
{ "TenantDatabases": [ { "TenantId": "Tenant001", "ConnectionString": "Server=.;Database=Tenant001DB;Trusted_Connection=True;" }, { "TenantId": "Tenant002", "ConnectionString": "Server=.;Database=Tenant002DB;Trusted_Connection=True;" } ] }
创建对应的配置模型类:
public class TenantDatabaseConfig { public string TenantId { get; set; } public string ConnectionString { get; set; } }
3. 编写多租户迁移执行逻辑
创建一个服务类来处理逐个租户的迁移操作,核心是为每个租户单独初始化FluentMigrator运行器:
using FluentMigrator.Runner; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; public class TenantMigrationService { public void MigrateAllTenants(List<TenantDatabaseConfig> tenantConfigs) { foreach (var tenant in tenantConfigs) { Console.WriteLine($"开始迁移租户 [{tenant.TenantId}] 的数据库"); // 为当前租户构建独立的迁移运行器 using var serviceProvider = CreateMigrationServiceProvider(tenant.ConnectionString); var runner = serviceProvider.GetRequiredService<IMigrationRunner>(); try { runner.MigrateUp(); Console.WriteLine($"租户 [{tenant.TenantId}] 迁移完成"); } catch (Exception ex) { Console.WriteLine($"租户 [{tenant.TenantId}] 迁移失败: {ex.Message}"); // 根据需求选择是否继续后续租户迁移 } } } private ServiceProvider CreateMigrationServiceProvider(string connectionString) { return new ServiceCollection() .AddFluentMigratorCore() .ConfigureRunner(rb => rb .AddSqlServer() // 替换为你的数据库驱动 .WithGlobalConnectionString(connectionString) // 指定包含迁移类的程序集 .ScanIn(typeof(InitialCreate).Assembly).For.Migrations()) .AddLogging(lb => lb.AddFluentMigratorConsole()) .BuildServiceProvider(); } }
4. 在程序启动时触发迁移
在Program.cs中读取配置并执行迁移:
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; var host = Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { config.AddJsonFile("appsettings.json", optional: false); }) .Build(); using var scope = host.Services.CreateScope(); var config = scope.ServiceProvider.GetRequiredService<IConfiguration>(); var tenantConfigs = config.GetSection("TenantDatabases").Get<List<TenantDatabaseConfig>>(); var migrationService = new TenantMigrationService(); migrationService.MigrateAllTenants(tenantConfigs); host.Run();
5. 可选:命令行批量迁移方案
如果偏好使用命令行工具,可以编写控制台程序循环调用dotnet fm命令:
using System.Diagnostics; foreach (var tenant in tenantConfigs) { var process = new ProcessStartInfo { FileName = "dotnet", Arguments = $"fm migrate -p SqlServer -c \"{tenant.ConnectionString}\" -a YourMigrationAssembly.dll", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using var cmd = Process.Start(process); cmd.WaitForExit(); Console.WriteLine(cmd.StandardOutput.ReadToEnd()); }
关键注意事项
- 确保所有租户数据库的Schema结构完全一致,否则迁移会出现兼容性问题
- 可添加数据库预检查逻辑(如判断数据库是否存在),避免迁移时出错
- 大规模租户场景下,建议加入异步执行、批量限流等优化措施
- 迁移失败时可根据业务需求选择重试、跳过或终止后续操作
内容的提问来源于stack exchange,提问作者Max Pane
相关产品推荐
相关产品推荐

