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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法更新数据库以匹配当前模型,因为存在挂起的更改相关的知识,希望对你有一定的参考价值。

我有一个在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(Action mustSucceedToKeepDatabase)+422 System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)+78 System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update()+ 12 YourTimeSite.Global.ApplyDatabaseMigrations()在c: Users Ahmed Desktop YourTimeSite YourTimeSite Global.asax.cs:55 YourTimeSite.Global.Application_Start(Object sender,EventArgs e)位于c: Users Ahmed Desktop YourTimeSite YourTimeSite Global.asax.cs:32

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

[HttpException(0x80004005):无法更新数据库以匹配当前模型,因为存在挂起的更改并且已禁用自动迁移。将挂起的模型更改写入基于代码的迁移或启用自动迁移。将DbMigrationsConfiguration.AutomaticMigrationsEnabled设置为true以启用自动迁移。] System.Web.HttpRuntime.FirstRequestInit(HttpContext context)+9947380 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context)+101

答案

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

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

另一答案

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

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

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

最后,我的泛型类型是我开发的通用实现,它们是不同的抽象层次。我在使用之间进行了测试:

  • DbMigrationsConfiguration,EF的基本DbContext配置
  • BaseConfiguration,我的抽象基础DbContext配置
  • <U>,允许用户传递他们的基础实现。

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

TLDR - 检查你是否使用带有泛型的SetInitializer,并确保你的泛型100%完全相同,而不是彼此的碱基/子类。

以上是关于无法更新数据库以匹配当前模型,因为存在挂起的更改的主要内容,如果未能解决你的问题,请参考以下文章

EF在MigrationHistory中创建InitialCreate,然后打开迁移并且InitialCreate有一个新的MigrationId导致挂起的迁移问题

AsyncTaskLoader onLoadFinished 有一个挂起的任务和配置更改

错误:无法 ALTER TABLE,因为它在尝试删除表中的列时有挂起的触发器事件

Perforce挂起的更改列表差异脚本

vs2013-执行签入挂起的更改,提示没有挂起的更改(实际代码已修改)

SQLServer恢复挂起的解决方案附加文件时候的提示“无法重新生成日志,原因是数据库关闭时存在打开的事务/用户,该数据库没有检查点或者该数据库是只读的。 ”数据库恢复