9

我正在研究将基于代码的 EF 迁移用于使用 EF 的产品。一切通常都运行良好,除了命令:

Add-Migration MyTestMigration

输出以下消息:

无法生成显式迁移,因为以下显式迁移处于挂起状态:[201206260845338_DannyTest]。在尝试生成新的显式迁移之前应用挂起的显式迁移。

原因是在构建时连接字符串是未知的,并且 EF 在 .\SQLExpress 上随机创建了一个名为“MyContextName”的数据库。我无法应用挂起的迁移,因为它引用了该数据库中不存在的数据库表 - 我们只是尝试使用迁移作为执行脚本的一种方式;

所以问题是:

  1. 如果我们不使用自动迁移(我们有 EnableAutomaticMigrations=false),为什么Add-Migration要求数据库是最新的,即使它对生成的(空)迁移绝对没有影响?我发现很难相信 MS 不打算使用这个用例,因为它的工作量很大。唯一“破碎”的事情是不影响任何行为的验证。

  2. 除了创建我们自己的 Add-Migration 命令之外,还有什么办法可以解决这个问题,该命令只是复制 EF 的功能,但跳过(看似不必要的)数据库最新检查?我试过传递各种参数,但到目前为止还没有成功。

编辑:

我实际上找到了解决这个问题的更好方法,但这并不是这些问题的真正答案,所以在这里添加它。希望有时间把它变成一篇博文

我想使用 Add-Migration 的唯一原因是因为 DbMigration 附带的所有内容。但我意识到,有了基类,我们基本上可以通过让基类从属性自动生成迁移 ID 来消除对所有这些的需求。我们所有迁移的目标都是相同的,因为模型状态不会改变。现在,我们只需像这样手动创建迁移(构建 ID 需要日期,以便 EF 以正确的顺序应用它们):

[Migration(2012, 6, 27, 12, 00, "Add new xxx fields for yyy")]
internal class MyNewMigration : MyDbMigration
{
    public override Up()
    {
        // ...
    }
    public override Down()
    {
        // ...
    }
}

该类MyDbMigration具有 Target/Source/Id 属性。Target 是硬编码的(与 Add-Migration 在第一次迁移中创建的值相同),Source 为 null,Id 是读取 MigrationAttribute 的一些反射。这意味着我们现在可以手动创建这些类;这不是很多努力,现在我们不必担心所有 IMigrationMetadata 的东西 :-)

4

2 回答 2

1

尝试注释掉您现有的迁移(那些尚未应用于在 .\SQLExpress 上创建的数据库的迁移)并重新运行您的应用程序。这应该用它需要的初始表填充本地数据库。

一旦本地数据库具有正确的结构,您应该能够取消注释您的迁移,然后使用 update-database 使本地数据库保持最新。然后,您将能够添加新的迁移。

还要记住 update-database 命令上有一个 -connectionString 参数,因此您可以将迁移定位到特定的服务器/数据库。

于 2012-06-27T06:17:42.523 回答
0

在我从解决方案中删除包管理器最初创建的原始自动生成的迁移代码之前,我看到了这个错误。

在 Danny 的情况下,这将是 201206260845338_DannyTest.cs。

于 2014-02-17T16:31:10.977 回答