代码优先添加迁移不断添加相同的列

Dav*_*eer 7 .net entity-framework ef-code-first ef-migrations

我的模型包含两个在初始创建和迁移后添加到模型类的属性.

public sealed class SomeModel
{
    ... other properties, which are fine.        
    public int PropertyOne { get; set; }
    public int PropertyTwo { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我最近的迁移包含:

public override void Up()
{
    ... other table being created.
    AddColumn("dbo.SomeModel", "PropertyOne", c => c.Int(nullable: false));
    AddColumn("dbo.SomeModel", "PropertyTwo", c => c.Int(nullable: false));
}
Run Code Online (Sandbox Code Playgroud)

目标数据库包含PropertyOnePropertyTwo列,该__MigrationHistory表包含创建表的迁移和添加列的迁移的条目.

当我运行Add-Migration以获得其他一些更改时,它还会再次包含这两个属性:

public override void Up()
{
    ... other changes.
    AddColumn("dbo.SomeModel", "PropertyOne", c => c.Int(nullable: false));
    AddColumn("dbo.SomeModel", "PropertyTwo", c => c.Int(nullable: false));
}
Run Code Online (Sandbox Code Playgroud)

可能是什么导致了这个?我还注意到,如果我恢复所有模型更改并尝试Update-Database(不应该做任何事情),我会收到错误:

无法更新数据库以匹配当前模型,因为存在挂起的更改并且已禁用自动迁移.将挂起的模型更改写入基于代码的迁移或启用自动迁移.将DbMigrationsConfiguration.AutomaticMigrationsEnabled设置为true以启用自动迁移.

可能是什么导致了这个?

Dav*_*eer 13

事实证明,在.designer.cs与迁移相关的类中有一个隐藏的模型快照.(这是IMigrationMetadata.Target,并且不是人类可读的.)导致问题的一系列步骤是:

  1. 创建模型的更改.
  2. 运行Add-Migration以创建更改的迁移.(这会创建隐藏IMigrationMetadata.Target值.)
  3. 注意到迁移建模方式存在错误,请直接更改模型类和迁移类.(这些IMigrationMetadata.Target值现在不同步.)
  4. 运行Update-Database以应用更改.

要摆脱困境,使用创建虚拟迁移Add-Migration Dummy,然后从Up()Down()方法中删除所有内容.

请注意,这Add-Migration确实警告过你; 当你跑步时Add-Migration,它会显示:

此迁移文件的Designer代码包含当前Code First模型的快照.此快照用于在您构建下一次迁移时计算模型的更改.如果您对要在此迁移中包含的模型进行其他更改,则可以通过再次运行"添加迁移虚拟"来重新构建它.

在我弄清楚问题是什么之前,这个警告没有任何意义,并且看到了隐藏的IMigrationMetadata.Target价值.

底线:不要手动保持模型和迁移Up()方法同步; 你必须重新运行Add-Migration才能正确设置隐藏值.