如何从实体框架噩梦中恢复 - 数据库已经具有具有相同名称的表



当update-database返回以下消息

时,如何使EF与代码同步恢复不丢失数据

错误消息:system.data.sqlclient.sqlexception(0x80131904): 已经是数据库中名为"的对象。

我最初将其作为一个自我纠缠的问题,因为我在Proble中挣扎了一段时间,还有一些同事,但不幸的是,我的答案被删除了,我无法恢复它。

由于我怀疑在人们试图"清理"旧迁移时会发生多次情况,所以我认为我会用逐步的说明进行记录。

描述我们在中发现自己的情况:我们无法创建新的本地数据库,因为INIT脚本不完整,并且无法将更新应用于生产数据库,因为迁移脚本会创建已经存在的表。而且,我们不想删除生产数据。

症状:无法运行 update-database 因为它试图运行创建脚本,并且数据库已经具有相同的表格名称。

错误消息:system.data.sqlclient.sqlexception(0x80131904): 已经是数据库中名为"的对象。

问题背景:要更详细地了解这一点,我建议您在此处观看两个视频:https://msdn.microsoft.com/en-us/library/dn481501(v = vs.113).aspx

总而言之,EF了解当前数据库的位置与代码所在的位置,该数据库基于数据库中的表格(dbo .__迁移史)。当它查看迁移脚本时,它试图重新审核它与脚本的最后位置。如果不能,它只是试图按顺序应用它们。这意味着,它可以返回到初始创建脚本,如果您查看UP命令中的第一部分,则该错误是在表上发生的。

解决方案:我们需要做的是欺骗EF以为当前数据库是最新的,而"不"应用这些创造命令是因为生产数据库已经存在。设置了生产数据库后,我们仍然需要能够创建本地数据库。

步骤1:生产DB清洁首先,备份您的生产DB。在SSM中,右键单击数据库中,选择"任务>导出数据层应用程序..."并按照提示进行操作。打开您的生产数据库并删除/删除DBO .__迁移史表。

步骤2:本地环境清洁打开您的迁移文件夹并删除它。我假设您可以在必要时从git中恢复全部。

步骤3:重新创建初始在软件包管理器中,运行"启用移民"(EF将提示您使用-ContextTypename,如果您有多个上下文)。运行"添加迁移初始 - 静脉"。这将创建初始脚本以根据当前代码从头开始创建数据库。如果您在以前的配置中有任何种子操作。

步骤4:技巧EF 在这一点上,如果我们运行 update-database ,我们将遇到原始错误。因此,我们需要欺骗EF来思考它是最新的,而无需运行这些命令。因此,进入您刚创建的初始迁移中的UP方法,并将其全部评论。

步骤5:更新数据库如果没有代码可以在UP过程中执行,EF将创建DBO .__ MigrationHistory表,并具有正确的条目,可以说它正确运行了此脚本。如果愿意,请去检查一下。现在,不按要求进行编码并保存。如果您想检查EF认为其最新情况,您可以再次运行更新数据库。它不会使用所有createTable命令来实现上升步骤,因为它认为它已经完成了。

步骤6:确认EF实际上是最新的如果您的代码尚未应用于迁移,这就是我所做的...

运行"添加移民失踪移民"这实际上将创建一个空脚本。因为代码已经存在,所以实际上有正确的命令可以在初始迁移脚本中创建这些表,因此我只是将创造和等效的drop命令切入上下方法。

现在,运行 update-database 再次观看,并观看其执行您的新迁移脚本,在数据库中创建适当的表。

步骤7:重新连接并提交。构建,测试,运行。确保一切都在运行,然后提交更改。

步骤8:让您的团队其他成员知道如何进行。当下一个人更新时,EF不会知道它的命中率是什么,因为它在不存在之前运行的脚本。但是,假设本地数据库可以被吹走并重新创建,那么这一切都很好。他们将需要删除本地数据库,并再次从EF添加创建它。如果他们有本地更改和待处理的迁移,我建议他们再次在主人上创建自己的数据库,切换到他们的功能分支,然后从头开始重新创建这些迁移脚本。

最新更新