有时,当在git分支之间切换,然后尝试运行解决方案时(通过针对该分支的进度定位适当的迁移来更新数据库之后),我收到数据库错误。
无法更新数据库以匹配当前模型,因为存在挂起的更改并且已禁用自动迁移。将挂起的模型更改写入基于代码的迁移或启用自动迁移。将DbMigrationsConfiguration.AutomaticMigrationsEnabled设置为true以启用自动迁移。
注意,程序是手动迁移。
无论如何,通过添加迁移添加迁移支持迁移,该迁移具有已在先前迁移中执行或创建的操作/内容,其中没有一个迁移被删除(我多次检查数据库以确认)。在尝试将数据库更新为该迁移时,控制台会出错:
每个表中的列名必须是唯一的....
这确认了内容正在尝试支架已经是数据库的一部分。
清空起伏并更新到它是一种适用的解决方法。如果在这样做之后立即添加了另一个迁移,它将为空,表示没有任何东西可以支撑。
通常我可以更新针对上次实际迁移的数据库,并删除空的迁移,并且它可以正常运行一段时间。但如果我用git做任何事情,它往往会被撤消。解决方法是可以接受的但耗时且烦人。我想知道是否有办法阻止这种情况发生。
编辑:我忘了提到我试图在我开始项目并重新开始之前进行迁移。它没有帮助。此外,脚手架几乎总是另一条线的迁移线的副本(至少最近,无论如何)。
答案 0 :(得分:0)
了解EF如何生成和执行迁移可能有助于您处理问题。
EF使用二进制模型快照来确定要包含在scaffolded迁移中的增量更改。快照作为代码的一部分存储,作为嵌入式资源文件,扩展名为.resx
,与迁移代码类同名。此外,执行Update-Database
时,快照存储在当前的本地数据库中。每次运行迁移时,都会在表__MigrationsHistory
中插入记录,快照将存储在Model
列中。
请注意,快照不是从数据库实际架构生成的,而是从Model类中的代码生成的。创建新迁移时,EF会动态生成当前Model类的快照,并将其与先前迁移的快照(再次,不是实际的数据库模式)进行比较。
当您切换代码分支时,您的代码会被修改,但您的本地数据库却没有,并且您从Git获得的代码可能与快照和__MigrationsHistory.Model
的内容不同步在您的数据库中。
然而,即使知道所有这些,也不容易解释您的问题,假设您恢复到以前的常见迁移。也许您在脚手架迁移中添加了一些手动更改,或者您添加了一些没有正确Up
代码的Down
代码。或者您的分支中有不同的模型代码,但您生成了具有相同名称的迁移。或者具有相同名称但时间戳不同的迁移,因此它们会在__MigrationsHistory
表中重复出现。无论如何,一旦数据库与代码迁移不同步,就很难将其恢复为同步。通常你只需删除它并从头开始创建它。
一些可能有帮助的建议:
在生成新迁移之前,请检查__MigrationsHistory
表的内容。确保MigrationId
列中最后一条记录中的值与上次代码迁移的名称,时间戳编号和所有内容相匹配。如果没有,请尝试使用Update-Database
和-SourceMigration
参数运行-TargetMigration
,将数据库降级到正确的模型版本。
如果您要更改代码分支,并且要通过使用较早的目标迁移运行Update-Database
来降级数据库,请在获取代码之前执行新的分支。您使用旧代码降级,并使用新代码进行升级。降级这种方式会从__MigrationsHistory
中删除受影响的记录,因此一旦获得新的分支代码,就不会保留旧模型代码中的任何内容。
您还可以手动删除__MigrationsHistory
中的记录,以避免再次应用迁移。但要小心,因为数据库的真实架构将保持不变。
This msdn page详细介绍。