如何按年份/版本分组数据库迁移并批量执行多目录迁移?
实现EF多迁移目录自动顺序执行的方案
核心思路
通过自定义DbMigrationsConfiguration和IMigrationsAssembly,让EF上下文自动扫描指定根目录下的所有迁移子目录,按版本号排序后依次执行迁移,无需手动切换配置中的版本值。
具体步骤
1. 定义自定义迁移配置类
继承DbMigrationsConfiguration<TContext>,在构造函数中完成迁移目录的扫描、排序,并加载对应程序集:
public class CustomMigrationsConfig : DbMigrationsConfiguration<YourDbContext> { public CustomMigrationsConfig() { AutomaticMigrationsEnabled = false; AutomaticMigrationDataLossAllowed = false; // 从app.config读取迁移根目录,默认值为"migrations" var rootDir = ConfigurationManager.AppSettings["MigrationsRoot"] ?? "migrations"; var basePath = AppDomain.CurrentDomain.BaseDirectory; // 获取所有子目录并按版本号升序排序 var migrationDirs = Directory.GetDirectories(Path.Combine(basePath, rootDir)) .Select(Path.GetFileName) .OrderBy(dir => Version.Parse(dir.TrimStart('v'))) .ToList(); // 加载所有迁移目录对应的程序集 var migrationAssemblies = migrationDirs.Select(dir => { var assemblyPath = Path.Combine(basePath, rootDir, dir, $"{typeof(YourDbContext).Namespace}.{dir}.dll"); return Assembly.LoadFrom(assemblyPath); }).ToList(); // 替换为自定义的多目录迁移程序集加载器 MigrationsAssembly = new MultiDirMigrationAssembly(migrationAssemblies, new YourDbContext()); } }
2. 实现多目录迁移程序集加载器
EF默认只支持单个迁移程序集,所以需要实现IMigrationsAssembly接口来加载多个目录的迁移类型:
public class MultiDirMigrationAssembly : IMigrationsAssembly { private readonly IEnumerable<Assembly> _assemblies; private readonly DbContext _context; public MultiDirMigrationAssembly(IEnumerable<Assembly> assemblies, DbContext context) { _assemblies = assemblies; _context = context; } public IEnumerable<Type> GetMigrationTypes() { // 从所有加载的程序集中筛选出DbMigration类型 return _assemblies.SelectMany(asm => asm.GetTypes() .Where(t => typeof(DbMigration).IsAssignableFrom(t) && !t.IsAbstract)); } public Migration CreateMigration(Type migrationType, string activeProvider) { return (Migration)Activator.CreateInstance(migrationType, _context); } public Type GetContextType() { return _context.GetType(); } }
3. 配置DbContext使用自定义迁移配置
在你的DbContext构造函数中指定初始化器为自定义配置:
public YourDbContext() : base("YourConnStringName") { Database.SetInitializer(new MigrateDatabaseToLatestVersion<YourDbContext, CustomMigrationsConfig>()); }
4. 执行迁移命令
直接在Package Manager Console中执行:
Update-Database
EF会自动按版本顺序执行migrations/下所有子目录中的未应用迁移,不管当前配置中指定的是哪个版本。
关键注意点
- 迁移目录命名必须遵循可解析的版本格式(如
v22.04、v23.01),确保排序逻辑能正确识别顺序。 - 每个迁移目录对应的程序集需正确编译并放置在对应目录下,否则会出现加载失败的问题。
- 如果使用.NET Core/.NET 5+,需调整配置读取方式(比如用
IConfiguration代替ConfigurationManager),但核心逻辑一致。
内容的提问来源于stack exchange,提问作者Creat
相关产品推荐
相关产品推荐

