EF6 Code First下新旧版本程序共用同一数据库方案咨询
EF6 Code First 零停机同库升级方案
核心思路是通过关闭EF自动初始化、增量独立建表、迁移版本隔离三个核心操作,实现新旧版本exe并行运行、共享同一数据库,全程不中断现有生产服务,也无需导出生产库到本地测试,具体操作步骤如下:
- 关闭EF默认的数据库自动初始化逻辑
EF6默认会在程序启动时校验数据库结构和当前模型的匹配度,一旦检测到不一致就会抛异常或者自动执行迁移,这是旧版本服务中断的核心原因。在新旧两个版本的程序启动入口都加入如下配置,彻底关掉这个自动逻辑:
如果当前正在运行的旧版生产exe暂时没法重新编译发布也不影响:EF6默认只会校验自己映射到的表结构是否匹配,数据库里多一张没有被旧版映射的独立表,完全不会触发旧版的校验异常,等后续旧版有正常迭代需求时补上这行配置即可。// 旧版生产上下文、新版上下文都要设置 Database.SetInitializer<你的旧版生产DbContext类型>(null); Database.SetInitializer<你的新版DbContext类型>(null);- 关闭EF默认的数据库自动初始化逻辑
- 生成独立增量建表脚本,无需生产库备份即可验证
禁止直接在生产库执行Update-Database命令。在本地开发环境给新增的实体类创建对应迁移,然后在包管理控制台执行如下命令生成纯SQL脚本:
拿到生成的脚本后,删掉所有和原有4张生产表相关的操作语句,只保留新增第5张表的建表、主键/索引创建逻辑,确保脚本不会修改任何原有表的结构、不会触碰原有表的数据。你只需要在本地建一个空库,按生产环境规则建好原来的4张表,执行这段脚本就能验证逻辑正确性,完全不需要恢复生产备份,符合客户的安全要求。选业务低峰期在生产库手动执行这段精简后的SQL,整个操作只会新增一张独立表,正在运行的旧版exe完全感知不到变化,不会出现服务中断。Update-Database -Script -SourceMigration: $InitialDatabase -TargetMigration: 新增实体对应的迁移名称- 生成独立增量建表脚本,无需生产库备份即可验证
- 配置迁移隔离,避免新旧版本冲突
新版程序不要直接复用旧版的DbContext执行迁移,建议新建一个继承自旧版生产上下文的新DbContext类,只在新上下文里添加新实体的DbSet和映射规则,同时给新版配置独立的迁移历史表,不要和旧版默认生成的__MigrationHistory表共用,避免旧版读到新版的迁移记录触发模型不匹配报错,参考配置如下:
// 新版上下文,继承原有生产上下文 public class ProductionV2DbContext : OriginalProductionDbContext { // 新增实体对应的DbSet public DbSet<NewEntity> NewBusinessTable { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 这里只配置新实体的映射规则,禁止修改原有4个实体的映射 } } // 新版专属迁移配置 internal sealed class V2MigrationConfig : DbMigrationsConfiguration<ProductionV2DbContext> { public V2MigrationConfig() { AutomaticMigrationsEnabled = false; // 指定独立的迁移历史表,和旧版完全隔离 this.MigrationsHistoryTable("__V2_MigrationHistory", "dbo"); // 禁止迁移时执行可能导致数据丢失的操作 this.AutomaticMigrationDataLossAllowed = false; } }- 配置迁移隔离,避免新旧版本冲突
- 并行验证后平滑切流
生产库执行完建表脚本后,先把新版exe部署到生产环境的独立目录,连接同一个生产库做验证:
- 确认正在运行的旧版exe所有业务操作正常,无任何报错
- 验证新版exe读写原有4张表的逻辑和旧版表现完全一致,无异常
- 验证新版对新增第5张表的增删改查操作符合预期
验证通过后,就可以按业务节奏逐步把用户切换到新版程序,旧版程序可以一直保留到所有用户完成切换后再下线,全程不会出现服务中断。
- 并行验证后平滑切流
关键注意事项:整个升级过程中,绝对不要修改原有4个实体的映射规则、不要给原有表加字段/改字段属性/加外键约束,所有数据库变更只针对新增的独立表,就能100%保证新旧版本兼容。如果后续需要调整原有表结构,等旧版程序完全下线后再操作即可。
内容的提问来源于stack exchange,提问作者Nitin Kumar
相关产品推荐
相关产品推荐

