无法使用现有数据库运行EF5迁移

时间:2013-07-19 01:28:26

标签: c# .net entity-framework-5 ef-migrations ef-database-first

首先,我已经阅读了这些问题/答案:

这些似乎都适用于EF5之前的EF版本,我的情况似乎不适合这些答案。所以,让我描述一下我的情况。

  1. 我的应用程序最初是使用EF4创建的,模型优先。我使用GUI设计器设计了我的数据库,并用它来生成我的数据库。
  2. 我已经运行并将数据收集到数据库中几个月了。我真的不能丢失这些数据。
  3. 我分支我的代码,使用NuGet安装EF5,并使用EF Power Tools通过右键单击新的类库项目并选择Entity Framework | Reverse engineer code first来从我的数据库生成我的模型。
  4. 我能够顺利地重新引用我的新项目,将我的项目转换为使用新的DbContext而不是ObjectContext,并删除了保存旧模型的EF4类库。该计划效果很好!
  5. 现在,我想尝试自动迁移,我在Ruby on Rails中有一些经验。这是我做的:

    1. Enable-Migrations。由于连接字符串和app.config被使用而有点麻烦,但最终得到了它。但是,this MSDN page表示这应该会自动生成第一次迁移,以使我达到我已经到达的程度。它没有。
    2. 执行Add-Migration InitialSchema以完成步骤1中未自动完成的操作。
    3. 向我的某个模型对象添加了一个属性,然后尝试运行Add-Migration AddSerialToLogEntries,并显示:
    4.   

      无法生成显式迁移,因为以下内容   显式迁移正在等待:[201307190100268_InitialSchema]。   在尝试生成之前应用挂起的显式迁移   新的显式迁移。

      尝试在我现有的数据库上应用迁移失败,这并不奇怪。

      我上面提到的其他答案基本上说我运气不好,但就像我说的那些是旧版本的实体框架。我有什么选择吗?

      在写这个问题时,我想我可以使用SQL Server Management Studio将我的数据导出到SQL脚本,删除整个数据库,让EF创建它,然后运行脚本来重新获取我的数据。 ..我会在明天有空的时候尝试,但我想知道是否还有其他选项,因为我不是100%确定会起作用,并且不喜欢在过程中插入的数据有任何错误。 / p>

2 个答案:

答案 0 :(得分:12)

  

Ran Enable-Migrations。因连接字符串而有点麻烦   以及哪个app.config被使用,但最终得到了它。然而,   这个MSDN页面说这应该已经自动生成了   第一次迁移让我到了我已经到过的地步。它没有。

     

Ran Add-Migration InitialSchema来完成那些不是   在第1步中自动完成。这很有用。

实际上,enable-migrations命令仅在已使用Code-First创建数据库时才创建初始迁移,在此情况下数据库包含__MigrationHistory表。如果此表不存在(当您具有以前从未使用Code-First创建的现有数据库时就是这种情况)enable-migrations仅创建Configuration类。您必须手动调用add-migration然后创建第一个迁移类。所以,你所看到的行为是预期的。

通常,如果您使用EF 5,则为迁移准备现有数据库的过程如下:

  • 在包管理器控制台中调用enable-migrations。项目中的Migrations文件夹和Configuration课程将被创建。

  • 打开Configuration类并在构造函数中设置AutomaticMigrationsEnabled = false(如果默认情况下尚未设置)。

  • 在包管理器控制台调用中

    add-migration -IgnoreChanges InitialSchema
    

    “InitialSchema”只是一个示例名称。您可以按照自己的意愿命名。将创建一个<Timestamp>_InitialSchema类,该类派生自DbMigration。由于Up标志,此类中的Down-IgnoreChanges方法为空。如果没有此标志,该类将包含一个迁移,以将整个模型添加到数据库中,这不是您想要的,因为现有数据库已包含数据库模式。

  • 在包管理器控制台中运行update-database。由于Up方法为空,因此此更新不会对现有架构执行任何操作,但会创建__MigrationHistory表(作为数据库中的系统表)并将第一条记录添加到此表包含当前EF模型的模型哈希值。

  • 可选的最后一步:如果您更喜欢使用自动迁移,请打开Configuration类并在构造函数中设置AutomaticMigrationsEnabled = true。如果您要继续进行基于代码的迁移,请留下标记false

此时您可以开始对模型进行更改。每次使用add-migration创建新迁移时,它将在修改之前基于您的模型,迁移类将仅包含必要的模式更改。

答案 1 :(得分:3)

我建议采用稍微不同的方法,让您处于可以使用迁移在开发环境中从头开始创建数据库的状态:

  1. 而不是致电add-migration -IgnoreChanges InitialSchema, 尝试使初始模式迁移的生成工作。 如你所说,这应该在你最初打电话时发生 Enable-Migrations。您可以尝试指向数据库连接 在一个不存在的数据库中,以使其工作。

  2. 因此,您的InitialSchema迁移将包含 创建数据库的逻辑就像你在那时一样 逆向工程。你需要注释掉内容 在您部署到所有环境之前,Up()Down() 已有现有数据库。

  3. 然后您可以取消注释这些方法的内容 在您的开发环境中,您可以删除数据库和 使用

    重新创建它们
    var migrator = new DbMigrator(new Configuration());
    migrator.Update();
    

    您将在__MigrationHistory中拥有全套迁移功能 表。这很重要,因为没有它你将无法添加新的 未来的迁移。