我遇到问题的场景如下:
- 使用 EF 4.1 创建的 Code First 模型和生成的相应数据库
- EF 升级到 4.3.1 并添加了迁移(使用 IgnoreChanges,因为没有模型更改)以开始使用迁移(创建了 __MigrtionHistory 表并删除了 EdmMetadata) - 我们称之为“InitialMigration”
- 模型发生了变化,比如添加了一个新属性并生成了一个添加相应列的迁移(我们称之为“NewPropertyMigration”),然后应用于开发数据库(使用我们的迁移到最新初始化策略版本)
- 当代码升级到生产时,数据库会按预期更新为新列
- 然后,当在 Dev 中创建一个全新的数据库并且因为它基于最新模型时,它将在创建后立即包含新列,但是当初始化策略运行时,它仍然发现“InitialMigration”和“NewPropertyMigration”为待处理但它们两者都失败了,因为 EdmMetadata 不存在所以没有什么可以删除并且新列已经存在所以无法添加
当我检查这个新数据库上的 __MigrationHistory 表时,它只包含“InitialCreate”条目,这样就可以解释为什么其他两个迁移被认为是挂起的。但是我看不出他们如何在没有被应用的情况下进入这个表,同时它们也不需要应用,因为数据库已经包含了它们所涵盖的任何更改。我错过了什么?
我只想补充一点,“InitialCreate”中的“模型”列与“NewPropertyMigration”中的不同似乎有点可疑,即使它们代表相同的模型。这可能是原因吗?
更新:这是我用来创建新数据库并同时自动应用任何迁移的代码
public class MigratePaymentsToLatestVersion<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext
{
public void InitializeDatabase(TContext context)
{
// Create a brand new database if it doesn't exist but still apply any pending migrations
context.Database.CreateIfNotExists();
var migrator = new DbMigrator(configuration);
migrator.Update();
}
}
更新 2:显示相同问题的更简单场景
在进一步调查这一点时,我已经能够在下面描述的更简单的场景中重现该行为:
- 创建简单的模型和上下文
- 在测试应用程序中添加一个实体 - 自动创建所有默认设置数据库并添加对象
- 启用迁移 - 生成“InitialCreate”迁移
- Update-Database - 命令不返回挂起的迁移,因为 'InitialCreation' 已经在 __MigrationHistory 中
- 删除数据库并重新运行测试应用程序 - 再次自动重新创建数据库
- 此时我无法添加任何其他迁移或运行更新数据库,因为“InitialCreation”迁移被视为待处理但无法应用,因为所有实体都已存在