EF6混合CreateDatabaseIfNotExists和MigrateDatabaseToLatestVersion方法

时间:2017-07-29 10:34:05

标签: entity-framework ef-migrations

我们希望使用EF6数据库初始化程序支持所有以下方案,以便从我们的EF6模型创建或更新现有数据库:

  1. 创建并初始化新数据库。
  2. 更新尚未包含__MigrationHistory表的现有(旧版)数据库。
  3. 更新已有__MigrationHistory表的现有(已迁移)数据库。
  4. 使用CreateDatabaseIfNotExists数据库初始化程序时,它仅涵盖第一个方案。但是,我们无法进一步发展我们的数据模型。

    将MigrateDatabaseToLatestVersion数据库初始化程序与创建基线数据库的InitialDatabase迁移一起使用时,我们可以支持方案1和3.但它无法升级现有的旧数据库,因为生成的SQL语句不是幂等的。他们失败了。 G。用"表' xy'已存在"错误。

    当使用具有空InitialDatabase迁移(= empty Up()方法体)的MigrateDatabaseToLatestVersion数据库初始化程序时,我们只能支持方案2和3,但我们无法从头开始创建新数据库。

    我正在寻找一种结合了两全其美并支持所有三种必需场景的方法。不幸的是,目前的EF6设计似乎不太可能。我面临的问题是使用反射发现DbMigration步骤,并且似乎没有(干净的)方法来拦截它。我想做的是写一个增强的"混合"数据库初始化程序: 1.检查数据库是否存在。 2.如果不是,则执行所有迁移(= MigrateDatabaseToLatestVersion的默认行为)。 3.否则检查它是否已启用迁移(即表__MigrationHistory存在)。 4.如果是,则仅执行挂起的迁移(= MigrateDatabaseToLatestVersion的默认行为)。 5.否则执行除第一个" InitialDatabase"之外的所有DbMigrations。移民。这也应该创建__MigrationHistory表并包括所有(!)迁移(包括第一个" InitialDatabase"迁移)。

    我找不到实施第5步的方法。

    我很高兴看到" hack"这让我可以捕获并忽略第一步升级操作的异常(使用众所周知的MigrationId)。我已经考虑过从DbMigrator派生一个类并用

    覆盖ApplyMigration方法
    try 
    { 
      base.ApplyMigration(...) 
    } 
    catch 
    { 
      ...ignore if migrationMetadata.Id=="my well-known id"..
    } 
    

    块。但这是不可能的,因为ApplyMigration是内部的。

    有关于此的任何想法吗?

0 个答案:

没有答案