【问题标题】:EF Code First Database migration error on second start第二次启动时EF Code First数据库迁移错误
【发布时间】:2014-11-08 03:49:33
【问题描述】:

我在生产环境中有一个带有本地数据库的 Web 应用程序。在新版本中,我决定更改数据库并添加数据库迁移。 我在 NuGet 控制台中运行了 Enable-Migrations。 程序已生成 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_InitialCreate201410141956597_WorkstationLastCallAdded 迁移 ID。

有人可以帮帮我吗?任何想法出了什么问题?为什么更新后第一次运行正常,第二次运行失败?

提前谢谢你。

【问题讨论】:

    标签: entity-framework-4 entity-framework-migrations


    【解决方案1】:

    IIRC,答案很简单。您有两个迁移:

    201410151540264_InitialCreate
    201410141956597_WorkstationLastCallAdded
    

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

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

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

    99999999999999_0001_WorkstationLastCallAdded
    

    一堆九确保此迁移早于 InitialCreate0001 反映了迁移的顺序。如果你想创建另一个迁移,你应该这样命名它:

    99999999999999_0002_SomeOtherFieldAdded
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2014-10-08
      • 1970-01-01
      • 2013-04-20
      • 1970-01-01
      • 2020-12-03
      • 2015-04-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      相关资源
      最近更新 更多