第二次启动时EF Code First数据库迁移错误

时间:2014-10-15 19:22:50

标签: entity-framework-4 ef-migrations

我在生产环境中有一个带有本地数据库的Web应用程序。在新版本中,我决定更改数据库并添加数据库迁移。 我在NuGet控制台中运行了启用迁移。 程序生成了201410141412423_InitialCreate.cs文件,因为我已有数据库 - 有一些代码初始化我的数据库模式。 然后我在模型工作站中添加了一个字段

public class Workstation
{
    public int Id { get; set; }

    [StringLength(15)]
    public string Name { get; set; }

    public DateTime LastCall { get; set; } //this field was added

    public string UserConfiguration { get; set; }

    private readonly ICollection<StatusBase> _statuses = new Collection<StatusBase>();

    public virtual ICollection<StatusBase> Statuses
    {
        get { return _statuses; }
    }
}

我在NuGet控制台中运行了 Add-Migration WorkstationLastCallAdded 命令。使用下一个代码生成了具有迁移逻辑的新文件:

public partial class WorkstationLastCallAdded : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.Workstations", "LastCall", c => c.DateTime(nullable: false));
    }

    public override void Down()
    {
        DropColumn("dbo.Workstations", "LastCall");
    }
}

我还在Global.asax文件中添加了下一个代码来更新我的数据库

protected void Application_Start()
{
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<AppDbContext, MigrationConfiguration>()); 
}

然后我构建并运行,一切正常。 当我将新构建部署到服务器时,有一个数据库文件,其中包含服务器上的一些数据。数据库有旧方案 - 没有LastCall字段。所以我希望迁移更新我的数据库,我不会丢失任何数据。 当我在部署后运行我的网站 - 一切正常。数据不会丢失,数据库也会正确更新。 如果我重新启动服务器或IIS并再次运行我的网站 - 我有一个错误。

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

当我打开本地数据库并观看_MigrationHistory表时 - 有两行 1410151540264_InitialCreate 201410141956597_WorkstationLastCallAdded 迁移ID。

是的,有人可以帮帮我吗?有什么想法会出错吗?为什么它在更新后首次运行时正常工作但在第二次运行时失败?

提前谢谢。

1 个答案:

答案 0 :(得分:0)

IIRC,答案非常简单。您有两次迁移:

201410151540264_InitialCreate
201410141956597_WorkstationLastCallAdded

InitialCreate miration比 WorkstationLastCallAdded 迁移更新。为什么?因为首次创建数据库并且没有迁移时, InitialCreate 会隐式添加到 _MigrationHistory 表中。在这种情况下, InitialCreate 的时间戳当然等于当前服务器时间。另一方面, WorkstationLastCallAdded 具有固定的时间戳,反映了运行Add-Migration WorkstationLastCallAdded命令的时间。因此,如果您创建数据库 之后您已创建 WorkstationLastCallAdded ,则 InitialCreate 将成为最新的。迁移。

接下来会发生什么? Db初始化程序搜索最新的迁移并找到 InitialCreate 。然后它将 InitialCreate 模型哈希与当前模型哈希进行比较,并发现这些哈希值是不同的(当然它们已经改变了你的模型!)。然后你得到了错误。

解决此问题的最简单方法是将 WorkstationLastCallAdded 时间戳(在迁移设计器文件中)重命名为以下内​​容:

99999999999999_0001_WorkstationLastCallAdded

一系列9确保此迁移早于 InitialCreate 0001反映了迁移的顺序。如果要创建另一个迁移,则应将其命名为:

99999999999999_0002_SomeOtherFieldAdded

希望这有帮助!