Chr*_*son 53 c# version-control asp.net-mvc-3 ef-migrations entity-framework-4.3
我有一个ASP.NET MVC3项目,它使用Entity Framework 4.3和代码优先方法.我使用迁移来使数据库保持最新.
该项目处于源头控制之下,我有许多分支机构.我刚刚意识到,当我想将一个分支合并到主分支中时会出现问题.由于我在两个分支中都创建了迁移文件,因此在合并时会出现重叠迁移,这可能会导致冲突.
有没有一种很好的方法来管理具有多个分支的项目中的迁移?
更新
一种方法是合并,然后删除在分支分离时创建的所有迁移文件,然后创建一个新的迁移文件,该文件包含从创建分支到重新合并之前的所有更改.这将适用于dev-environment,您可以在其中转储数据库并使用所有迁移文件重新构建它.那么问题就是现实环境.由于您无法回滚到创建分支的时间而没有丢失数据的风险,因此当您尝试使用新的迁移文件来更新实时数据库时会发生冲突.
old*_*ard 17
我认为接受的答案是不正确的.在类似问题上处理实体框架迁移合并冲突有一个更好的解决方案.
合并后您需要做的就是在目标分支中重新构建迁移的元数据.也就是说,您不需要重新调整上/下代码,只需重新调整resx文件中的状态.
add-migration [the_migration_to_rescaffold_metadata_for]
Run Code Online (Sandbox Code Playgroud)
如果合并中的其他迁移更改了数据库,导致迁移不再可运行或产生意外结果,则此过程将失败.话虽这么说 - 我相信这是一个非常罕见的情况,因为大多数迁移应该是自动生成的,或者至少不依赖于迁移本身没有改变的其他表.非常小的问题,但需要注意的一个问题.
一个这样的案例可能是fxp(我想不出一个更好的例子)
列foo是一个int,行包含[0,1,2]
从分支A迁移A将foo更改为boolean(0将自动变为false,> 0将变为true)
从分支B迁移B将foo更改为字符串.它期望它是一个int,但它是一个布尔值,但迁移将成功.数据将丢失,因为创建迁移B时,行将包含["0","1","2"].当迁移A将列更改为布尔值(并且成功完成并且具有预期结果)时,行现在将包含["0","1","1"],而迁移B将具有与在分支B.
可能存在更多边缘情况,解决方案可能出现问题.但是,如果迁移上/下代码不依赖于合并中另一个迁移所更改的内容,则应该可以很好地更新迁移中的元数据.
Bil*_*ang 17
编辑:我的一位同事发现了一个更容易做到这一点,我在底部留下了原始答案的完整性.
(非常重要)实时环境中的迁移不得与当前分支中的迁移冲突,否则您需要重做所有迁移并手动解决数据模型更改冲突.
update-database,它应该从您的分支运行迁移,并抱怨'无法更新数据库以匹配当前模型等等等等.'add-migration MergeBranchBToMaster -ignoreChanges,这将创建一个空迁移.update-database了步骤3中的魔术基本上告诉EF关闭不匹配的模型,因此非常确定您的迁移不会与实时环境中的迁移冲突.如果他们这样做,您始终可以创建SQL脚本来推送缺少的迁移(这实际上是首选方法).
原始答案
基于@Ladislav Mrnka的答案,我找到了一个相当直接的解决方案.这将适用于实时环境[1],您只需要小心不要更改任何已部署的迁移.
在合并之前,请记下您添加的迁移(MyMigration)及其先前的迁移(BaseMigration)
在git中合并分支
打开包管理器控制台,然后运行:UPDATE-DATABASE -TargetMigration:BaseMigration.这将使您的数据库恢复到应用任何冲突迁移之前的状态
删除本地迁移(MyMigration)
运行:UPDATE-DATABASE.这将应用在其他分支中完成的所有较新迁移.
运行:ADD-MIGRATION MyMigration.这将根据当前的数据库状态重新生成本地迁移,例如git -rebase.
运行:UPDATE-DATABASE.使用本地迁移更新数据库.
如果您有多个本地迁移,这也适用,但它会将它们全部合并为一个.
[1]通过使用实时环境,我的意思是生成的迁移可以应用于可能已经应用了部分/全部其他分支的迁移的实时环境.这些步骤本身纯粹是出于开发目的.
Lad*_*nka 13
合并迁移是IMHO手动任务.迁移代码的一部分是自动生成的,我们通常不合并自动生成的代码 - 而是在合并后再次运行自动生成.
在ADO.NET团队提供一些建议之前,我会遵循简单的原则:
如果您的分支包含多个迁移步骤(版本),您将丢失它们,并且您将以分支之前和合并之后的两个版本结束.
编辑:
它不适用于现场环境.这里的问题是开发过程本身.如果你有实时环境,你应该保持其分支不受影响(除了小错误修复).如果您继续使用生产部署在该分支中进行开发,同时在单独的分支中构建另一个版本而不进行持续集成(=将更改连续更改回主分支以将新开发与主代码库集成)问题.我认为一般来说,迁移无法解决这个问题.
在这种情况下,唯一的选择可能是从合并解决方案中删除所有迁移并MigrationHistory从数据库中删除表.您可以再次启用项目上的迁移,并添加初始迁移以使用当前数据库作为起始点=无法返回到先前版本,因为不存在有关先前迁移的信息.
Rowan Miller在第9频道:移植 - 团队环境中制作了关于此主题的精彩视频.它指的是实体框架6.
它描述了第一个开发人员A和B正在处理同一模型而A先检查的情况.现在,开发人员B必须处理他从A获得最新版本时遇到的问题.
这与在不同分支之间存在冲突基本相同,因为一般问题是合并迁移更改同时完成但有效地具有模型的不同源状态.
解决方案是:
UpdateDatabase开发人员B 的命令仍然会失败(错误消息:"无法更新数据库以匹配当前模型,因为存在挂起的更改...")IgnoreChanges选项创建"空迁移" :Add-Migration NameOfMigration -IgnoreChanges
然后UpdateDatabase命令将成功.
问题的根源
更新数据库时发生的错误源是因为EF在迁移文件中的resx文件中存储迁移引用的模型的快照.
在这种情况下,获取/合并开发人员A所做的更改后,"当前模型"的开发人员B快照不正确.
| 归档时间: |
|
| 查看次数: |
19590 次 |
| 最近记录: |