你如何获得EF回到同步的代码,而不会丢失数据时更新数据库返回以下消息
错误消息信息:System.Data.SqlClient.SqlException(0x80131904):有已经在数据库中名为“”的对象。
你如何获得EF回到同步的代码,而不会丢失数据时更新数据库返回以下消息
错误消息信息:System.Data.SqlClient.SqlException(0x80131904):有已经在数据库中名为“”的对象。
我最初写这是一个自我回答的问题,因为我曾与proble一段时间挣扎,因为有几个同事,但不幸的是,我的答案被删除,我不能恢复。
因为它是我怀疑可能发生几次,因为人们尝试“清理”老迁移的情况,我想我会用一步一步的指示将其记录下来。
描述的情况看,我们发现自己在 :我们不能不能创建新的本地数据库,因为初始化脚本是不完整的,因为迁移脚本创建一个已经存在的表不能更新应用到生产数据库。 而且,我们不希望删除的生产数据。
症状 :因为它试图运行创建脚本和数据库已经与名称相同的表不能运行更新的数据库 。
错误消息信息:System.Data.SqlClient.SqlException(0x80131904):有已经在数据库中名为“”的对象。
问题背景 :为了了解得更详细,我建议你看这里引用的两个视频: https://msdn.microsoft.com/en-us/library/dn481501(v=vs.113).aspx
总之,EF理解在当前数据库是与其中的代码是基于数据库名为DBO .__ MigrationHistory一个表中。 当它看起来在迁移脚本,它会尝试reconsile它最近在与脚本。 如果不能,它只是试图以应用它们。 这意味着,它可以追溯到最初的创建脚本,如果你看一下在命令中的第一个部分,它会是错误发生在上CreeateTable为表。
解决方法 :我们需要做的是EF欺骗,以为当前的数据库是最新的,而“不”应用这些CREATETABLE命令,因为生产数据库已经存在。 一旦生产DB设置,我们仍然需要能够创建本地数据库以及。
第1步:制作DB干净首先,使您的生产数据库的备份。 在SSMS,右键单击数据库,选择“任务>导出数据层应用程序...”并按照提示操作。 打开你的生产数据库和删除/删除DBO .__ MigrationHistory表。
第2步:本地环境整洁打开你的文件夹迁移和删除。 我假设你可以得到这个从SVN都回来了,如果必要的。
第3步:重新创建初始在包管理器,运行“启用的迁移”(EF会提示你使用-ContextTypeName如果您有多个上下文)。 运行“添加 - 迁移初始-verbose”。 这将创建初始脚本来创建基于当前的代码从头开始数据库。 如果你在前面Configuration.cs任何种子操作,然后复制跨越。
第4步:天雷EF在这一点上,如果我们跑了更新的数据库 ,我们会得到原来的错误。 所以,我们需要EF欺骗,以为它是最新的,不运行这些命令。 所以,进入最高法刚刚创建的初始迁移和评论这一切了。
第5步:更新数据库内没有代码对过程执行,EF将创建正确的入口说它正确运行此脚本DBO .__ MigrationHistory表。 你去看看,如果你喜欢。 现在,取消这些代码并保存。 如果你想检查EF认为它是最新的,你可以再次运行更新的数据库 。 它不会运行向上步所有的CREATETABLE命令的,因为它认为它已经做到了这一点。
第6步:确认EF实际上是最新的 。如果你有这样的尚未有迁移应用到它的代码,这是我做过什么?
运行“添加 - 迁移MissingMigrations”这实际上将创建一个空的脚本。 由于代码在那里已经有实际上创建初始迁移脚本这些表正确的命令,所以我只是削减CREATETABLE和相当于降命令为向上和向下的方法。
现在,再次运行更新,数据库 ,看它执行新的迁移脚本,在数据库中创建适当的表。
第7步:重新确认和承诺。 构建,测试,运行。 确保一切运行,然后提交更改。
第8步:让你的团队的其他成员知道如何着手。 当旁边的人的更新,EF不会知道什么打它因为它之前就运行的脚本不存在。 但是,假设本地数据库可以被吹走并重新创建,这是所有好。 他们将需要再次从EF放弃他们的本地数据库,并添加创建它。 如果他们有局部变化和正在申请移民,我建议他们再在主创建自己的数据库,切换到它们的特性分支,并重新从头开始创建的迁移脚本。