无法更新数据库以匹配当前模型,因为存在待定更改

时间:2016-08-15 14:19:47

标签: asp.net-mvc entity-framework ef-code-first

我有一个在visual studio 2013环境中构建的项目,首先使用EF 5代码构建Db。 我已经让我的API工作了很长时间,但突然间我开始收到这样的错误:

  

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

当我尝试达到API的终点时。我尝试添加新的迁移,然后更新数据库但仍然出错。然后我删除整个数据库并使用EF重新创建。我的API的端点开始工作正常,但我再次开始在网页上收到此错误。我在配置文件中将自动迁移设置为true。我真的不知道为什么会一遍又一遍地发生这种情况。它让我非常沮丧。 这是错误的完整堆栈跟踪:

  
    

  
     

[AutomaticMigrationsDisabledException:无法将数据库更新到   匹配当前模型,因为有待更改和   自动迁移已禁用。编写待定模型   更改基于代码的迁移或启用自动迁移。组   DbMigrationsConfiguration.AutomaticMigrationsEnabled为true以启用   自动迁移。]
  System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1   pendingMigrations,String targetMigrationId,String lastMigrationId)   +579 System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)+445
  System.Data.Entity.Migrations。<> c__DisplayClassc.b__b()+ 13
  System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(动作   mustSucceedToKeepDatabase)+422
  System.Data.Entity.Migrations.DbMigrator.Update(字符串   targetMigration)+78
  System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update()+12   YourTimeSite.Global.ApplyDatabaseMigrations()in   C:\用户\艾哈迈德\桌面\ YourTimeSite \ YourTimeSite \的Global.asax.cs:55
  YourTimeSite.Global.Application_Start(Object sender,EventArgs e)in   C:\ Users \用户艾哈迈德\桌面\ YourTimeSite \ YourTimeSite \ Global.asax.cs中:32

     

[HttpException(0x80004005):无法更新数据库以匹配   当前模型,因为有待更改和自动   迁移已禁用。将待处理的模型更改写入a   基于代码的迁移或启用自动迁移。组   DbMigrationsConfiguration.AutomaticMigrationsEnabled为true以启用   自动迁移。]
  System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext的   上下文,HttpApplication app)+9966013
  System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr的   appContext,HttpContext上下文,MethodInfo []处理程序)+118
  System.Web.HttpApplication.InitSpecial(HttpApplicationState状态,   MethodInfo [] handlers,IntPtr appContext,HttpContext context)+172
  System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr的   appContext,HttpContext context)+352
  System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr的   appContext)+296

     

[HttpException(0x80004005):无法更新数据库以匹配   当前模型,因为有待更改和自动   迁移已禁用。将待处理的模型更改写入a   基于代码的迁移或启用自动迁移。组   DbMigrationsConfiguration.AutomaticMigrationsEnabled为true以启用   自动迁移。]
  System.Web.HttpRuntime.FirstRequestInit(HttpContext context)+9947380   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context)   101

4 个答案:

答案 0 :(得分:4)

这里确实没有足够的方法来诊断问题的根本原因,但通常情况下,如果您的数据库以某种方式与您的实体类不同步,您将只会收到该错误。如果您确实不相信,则可以通过从生产数据库中删除_MigrationHistory表来禁用此异常。此时,EF会将数据库视为现有数据库,并且不再提示您进行迁移。相反,只有在发现意外/缺失列或模式失步导致的其他SQL错误时,才会获得异常。在某些方面,虽然这样做更好,好像确实存在某些问题,但你会更好地了解到什么是关闭的,而不是被广泛告知你需要迁移。

但是,删除迁移历史记录表意味着如果您确实对实体类进行了更改,那么您将负责保持同步。一般来说,这不是问题,反正。无论如何,对生产数据库运行迁移是一个糟糕的主意,因此这实际上迫使您在必要时显式更新模式,希望使用适当的变更管理策略。

答案 1 :(得分:1)

我对此有很多麻烦,但是对我来说,答案是排除中间数据库迁移项,这些项会更改已经使用这些更改创建的表。如果我对此处的操作了解更多,我想我会遵循上面DbContext设置中的建议。

正在运行的更新数据库产生了相同的错误,但是:

  • 添加一个空迁移(通过PM),然后update_database有效

add-migration EmptyMigration

然后运行

update-database

此时,迁移运行没有错误。

  • 至少需要进行几次迁移,才能排除在项目之外(不了解CodeFirst项目是如何创建这些迁移的,因此不需要这些迁移,因此可以“排除”)。
  • Project Migrations包括一些中间步骤,这些步骤更新了EntityFramework已经应用的表结构(Entity Framework新手,我正在使用udemy的CodeFirst示例-MVC5课程)
  • 最初是“无法为...创建显式迁移”(VS2019)
  • 然后“没有待处理的显式迁移。解码时发现无效数据。”
  • 按照说明删除obj文件夹,然后从Nuget清除缓存,没有任何结果。

  • 接下来,尝试使用SSMS删除并使用空数据库(我正在运行SQL Server的开发人员版本,但Express相同)重新创建数据库。这部分可能需要也可能不需要。

  • 启动项目,发现它是Net Framework 4.5,因此已更新为4.7。同样,不确定是否需要。该示例项目是为Community Edition 2013构建的。

  • 重新启动项目(VS2019)

  • 执行上述两个步骤,现在一切正常。

答案 2 :(得分:0)

如果您在DbContext实现中做任何手动操作,我的情况可能会对您有所帮助。

就我而言,在我的DbContext构造序列中,我是手动执行迁移检查。换句话说,我正在使用Database.SetInitializer

在短短的几行中,我正在初始化上下文并弄乱SetInitializer。作为其中的一部分,我还在玩初始化策略MigrateDatabaseToLatestVersion<TContext, TMigrationsConfiguration>

最后,我的通用类型是我开发的通用实现,它们是不同的抽象级别。我在以下之间使用 typing 进行了测试:

  • DbMigrationsConfiguration,EF的基本DbContext配置
  • BaseConfiguration,我的抽象基础DbContext配置
  • <U>,允许用户通过我的基础实施。

最后,事实证明所有的SetInitializer调用和DbContext实例化都需要使用<U>或可能只是相同类的相同抽象级别。

TLDR -检查是否将SetInitializer与泛型一起使用,并确保所有泛型完全相同,而不是彼此的基类/子类。

答案 3 :(得分:0)

在数据库初始化程序中,将AutomaticMigrations设置为 true ,然后将其恢复为 false ,这将解决此问题:

internal class MyDatabaseInitializer : MigrateDatabaseToLatestVersion<MyDBContext, MyConfiguration>{

}

internal sealed class MyConfiguration : DbMigrationsConfiguration<MyDBContext>{

    public MyConfiguration(){
        AutomaticMigrationsEnabled = true;
    }
}