我正在研究将基于代码的 EF 迁移用于不使用 EF 的产品。一切通常都运行良好,除了命令:
Add-Migration MyTestMigration
输出以下消息:
无法生成显式迁移,因为以下显式迁移处于挂起状态:[201206260845338_DannyTest]。在尝试生成新的显式迁移之前应用挂起的显式迁移。
原因是在构建时连接字符串是未知的,并且 EF 在 .\SQLExpress 上随机创建了一个名为“MyContextName”的数据库。我无法应用挂起的迁移,因为它引用了该数据库中不存在的数据库表 - 我们只是尝试使用迁移作为执行脚本的一种方式;
所以问题是:
如果我们不使用自动迁移(我们有 EnableAutomaticMigrations=false),为什么
Add-Migration
要求数据库是最新的,即使它对生成的(空)迁移绝对没有影响?我发现很难相信 MS 不打算使用这个用例,因为它的工作量很大。唯一“破碎”的事情是不影响任何行为的验证。除了创建我们自己的 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 的东西 :-)