EntityFramework 6现有数据库和新数据库的迁移?

时间:2013-11-07 09:07:32

标签: c# entity-framework migration entity-framework-6 entityspaces

在我们的软件中,我们拥有现有数据库的客户群。数据库目前通过EntitySpaces访问,但我们想切换到EntityFramework(v6),因为不再支持EntitySpaces。我们还想使用迁移功能。禁用自动迁移,因为我们只希望允许数据库迁移到管理员用户。

我们从现有数据库生成EF模型。这一切都运行良好,但我们遇到的真正问题是,以编程方式区分与模型匹配但尚未转换为EF(缺少MigrationsHistory表)的现有数据库,以及空/新数据库。转换现有数据库适用于空迁移,但对于新数据库,我们还需要包含完整模型的迁移。迁移链中的初始迁移始终与现有数据库发生冲突。当然,我们可以使用外部SQL脚本或ADO命令创建一个变通方法,创建并填充MigrationsHistory表。但这是我们想要避免的,因为我们的一些客户使用MsSql数据库,有些使用Oracle。所以我们真的想保留EF提供的抽象层。

有没有办法让EF通过基于代码的迁移处理现有数据库和新数据库,而不回退到非EF解决方案?

1 个答案:

答案 0 :(得分:6)

我最初的建议是捕获CreateTable引发的异常,但事实证明这是在不同的地方执行的,所以这不能被困在异常中。

最简单的处理方法是使用Seed方法创建初始数据库(如果不存在)。要做到这一点......

  1. 从空白数据库开始,添加初始创建迁移并获取生成的SQL

    Add-Migration InitialCreate
    Update-Database -Script
    
  2. 保存此脚本。您可以将它添加到资源,静态文件中,或者如果您真的需要,可以将其保留在代码中,这取决于您。

  3. 删除InitialCreate迁移中的所有代码(使用空白的Up()和Down()函数)。这将允许您的空迁移运行,从而生成MigrationHistory表。

  4. 在迁移配置类中,您可以使用context.Database.SqlQuerycontext.Database.ExecuteSqlCommand动态查询和执行SQL。测试主表是否存在,如果不存在,则执行上面生成的脚本。

  5. 这不是很整洁,但实施起来很简单。测试一下,因为Seed方法在每次迁移运行后运行,而不仅仅是初始运行。这就是为什么你需要在做任何事情之前测试主表的存在。

    更复杂的方法是为迁移编写“CreateTableIfNotExists”方法,但这将涉及使用Reflection来调用DbMigration类中的内部方法。