实体框架合并噩梦
我们采用了实体框架,我们发现当多个人在各自的源代码控制分支中进行孤立的更改时,当他们合并在一起时会出现巨大的冲突,从而导致模型文件损坏。
我们倾向于强制对文件进行独占检查,但我想避免这种情况。
我的问题是......
是否有更好的比较工具可以更好地处理这个问题,或者我们可以采取另一种方法?
如果可能的话,寻找经过验证的东西。
新更新: 对于那些遇到这个问题的人来说,它是基于旧的 EF 的。我建议转而使用 DbContext 而不是 EDMX。这里有很多关于它的信息。在我看来,数据库优先或代码优先的简单性远远超过了设计者的损失。
更新: 我们通过强制对文件进行独占更改来解决此问题。通过添加这个过程,我们完全消除了任何问题。虽然这不是理想的解决方案,但它是最可靠且最容易实施的。
We've adopted the Entity Framework and we're finding that when multiple people make isolated changes in their individual source control branches, there are massive conflicts when they come together in a merge, resulting in broken model files.
We're leaning in the direction of forcing exclusive check outs on the file, but I'd like to avoid that.
My question is...
Is there a better compare tool that would handle this better, or is there another approach we could take?
Looking for something that is proven if possible.
NEW UPDATE:
For those of you that come across this question, it is based on old EF. I suggest moving to using DbContext over EDMX. There is a lot of info here on SO about it. The simplicity of Database first or Code first far outweighs the loss of the designer in my opinion.
UPDATE:
We resolved this issue by forcing exclusive changes to the file. By adding this process we completely eliminated any issues. While this was not the ideal solution, it was the most reliable and easiest to implement.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
克雷格·斯图茨 很好地解释了设计器相关的 xml(实体和关联等在设计表面上的位置)导致了这里的大多数问题。然而,
edmx:Runtime
元素内的冲突解决是非常容易实现的。处理设计器相关 xml 中的冲突的最佳策略是通过牺牲任何自定义布局并恢复为默认布局来完全绕过它们。
技巧是删除
元素的所有内容。设计器将毫无问题地打开并应用默认布局。以下是将使用默认布局打开的 EDMX 文件的示例。请注意,
元素的内容也被删除,但这只是为了简洁起见 - 它不是解决方案的一部分。请注意,此处应用的默认布局与选择“图表 | 图表”时生成的布局不匹配。设计器上下文菜单中的布局图正是我所期望的。
更新:从Entity Framework 5开始,这得到容易一点。 多图表支持 在那里添加将图表相关的 xml 卸载到单独的文件中。请注意,我在 edmx 文件中仍然有一些与图表相关的旧标签,这些标签经历了多次实体框架升级。我只是从 edmx 文件中删除了名为“Diagrams”(包括子项)的标签。
Craig Stuntz does a good job of explaining that it is the designer related xml (the positions of entities and associations etc on the design surface) that causes most of the problems here. Conflict resolution within the
edmx:Runtime
element however, is very achievable.The best strategy for dealing with conflicts in the designer related xml is to bypass them altogether by sacrificing any custom layout and reverting to a default layout.
The trick is to remove all of the content of the
<Diagrams>
element. The designer will open without any problem and apply a default layout.The following is an example of an EDMX file that will open with a default layout. Note that the content of the
<edmx:Runtime>
element was also removed however this was for brevities sake only - it is not a part of the solution.Note that the default layout that is applied here does not match the one that results when you select
Diagram | Layout Diagram
from the designer's context menu which is what I would have expected.Update: As of Entity Framework 5, this gets a bit easier. The multiple diagram support added there offloads the diagram related xml to separate files. Note that I still had some old diagram related tags in an edmx file that had experienced a number of Entity Framework upgrades. I simply deleted the tag named Diagrams (including children) from the edmx file.
有一些 本文中处理大型实体框架模型的策略。你可以考虑使用它们。然而,我发现 EDMX 重新生成的大部分痛苦来自于通过 GUI 设计器上的拖放进行的更改。另一方面,从数据库或通过属性窗口执行更新模型往往会以相当合理的方式进行更改,并且合并并不困难。
据我所知,最大的问题是概念/映射/存储模型中视觉对象模型的布局信息位于同一个文件中。换句话说,问题不在于文件本身的大小或对实体模型本身所做的更改,而在于当您将对象拖放到 GUI 设计器上时发生的大规模重新排列。我希望 GUI 设计器布局和概念/映射/存储模型位于不同的文件中。我相信这将消除合并模型更改的大部分痛苦。
因此,我们有一个半官方政策,不更改模型的图形布局。这并不是什么太大的损失,因为当您的模型中有几十个以上的实体时,一页的 GUI 设计器无论如何都没有真正的用处。它确实使合并变得更加容易。
实体框架版本 4 将提供基于 T4 模板生成工件的选项。我不是专家,但可以使用 T4 模板将 GUI 布局信息导入到不同的文件中。
There are some strategies for dealing with large Entity Framework models in this article. You could consider using them. However, I have found that most of the pain with the regeneration of the EDMX comes from changes made via dragging and dropping on the GUI designer. On the other hand, doing Update Model From Database or via the properties window tends to make changes in a fairly sensible manner, and does not tend to be difficult to merge.
The biggest problem, as far as I can see, is that the layout information for the visual object model in the conceptual/mapping/storage models are in the same file. In other words, the problem is not so much the size of the file itself or the changes made to the entity model itself, but the wholesale rearrangement which happens when you drag and drop an object on the GUI designer. I wish the GUI designer layout and the conceptual/mapping/storage models were into different files. I believe this would eliminate most of the pain with merging changes to the model.
Therefore, we have a semi-official policy of not making changes to the graphical layout of the model. This is not much of a loss, because when you have more than a couple dozen entities in your model, the one-page-only GUI designer is not really useful anyway. And it certainly makes merges a lot easier.
Version 4 of the Entity Framework will have an option to do artifact generation based on T4 templates. I'm no expert, but it may be possible to coax the GUI layout information into a different file using a T4 template.
正如您所说,一种选择是锁定文件。
另一种可能的选择是通过团队中的一个人来路由所有模型更改。
另一种选择是将文件分成更小的文件(例如每个类一个),可能会在此过程中留下一些设计人员的支持。
另一种选择是创建您自己的流程,可能使用 XSLT 来转换 EDMX 文件,但我不确定这到底是什么样子,designer.cs 文件是非常难以合并的文件。
另一种选择是考虑不同的 ORM。
我不确定他们是否会在 EF 的下一版本中对此进行任何改进。将如此多的数据放入一个文件中并不意味着任何类型的可扩展性(但 LinqToSql 做了同样的事情 - 在这种情况下,Damien Guard 创建了一些 T4 模板来分解文件,不确定 EF 是否存在类似的东西)。
As you said, one option is locking the file.
Another possible option is to route all model changes through one individual on the team.
Another option is to break the file apart into smaller files (like one per class), possibly leaving behind some designer support in the process.
Another option is to create your own process, potentially using XSLT to transform the EDMX file, but I'm not sure exactly what this would look like, the designer.cs file is the massive difficult to merge one.
Another option is to consider a different ORM.
I'm not sure if they are doing anything to improve this in the next version of EF. Throwing that much data in a single file doesn't imply scalability of any kind (Yet LinqToSql does the same thing - In that case Damien Guard created some T4 templates to break the file apart, not sure if something similar exists for EF).
事实上,正是因为这个原因,我试图说服我的公司采用 Code First,但不幸的是,结果被关闭了。他们喜欢能够使用设计师。不幸的是,我在上次生产部署中遇到了问题,其中一个 WCF 服务有大约 10 个端点来支持多个使用者,并且在合并过程中,EDMX 文件的 CS 部分中有几个重复的条目。
在我的个人项目中,我专门使用 Code First。对我来说,这就是我更喜欢手动变速箱而不是自动变速箱的原因。当然,模型设计者可能会更容易(有时,正如我们所讨论的),但是通过 Code First,您可以更直接地控制正在发生的事情。就像手动变速箱一样。 :)
I actually tried to convince my company to go to Code First for this very reason, and was shut down, unfortunately. They like being able to use the designer. Unfortunately, I ran in to issues on our last production deploy where one of our WCF services has about 10 end points in it to support multiple consumers, and in the process of merging, there were several duplicated entries in the C-S section of the EDMX file.
In my personal projects, I'm using Code First exclusively. To me, it's the same reason I prefer manual over automatic transmission. Sure, the model designer may be easier (sometimes, as we've discussed), but with Code First, you get much more direct control of what's going on. Just like a manual transmission. :)
我对 EF 并不是特别熟悉,但我也遇到过一些关于超详细和超详细的问题。脆弱的自动生成代码。在每种情况下,关于如何合并的最佳答案都是“不要”。在您的场景中,这可能意味着以下两件事之一:
1) 收紧您的代码升级模型,以便 EF 代码仅朝一个方向流动。换句话说,每个冲突都将被解决为“从源分支复制”(AcceptTheirs)或“保持目标不变”(AcceptYours),每个人都应该提前知道哪个是哪个。最常见的是,当将新测试的代码提升到分支树的稳定节点时,您需要 AcceptTheirs;当将修复合并回不稳定/开发分支时,您需要 AcceptYours。 (如果有 >1 个开发分支,那么您需要对事物进行分区,以便只有在给定分支中工作的团队拥有的 EF 代码才遵循后一个规则。他们无意更改的任何内容都应该被其他团队覆盖来自集成分支的代码,如有必要,请使用 AcceptTheirs。)
"Merge down, copy up"
2)从字面上看不要合并它们;从进程中完全排除 EF 代码。当集成分支需要更改数据库和/或 ORM 时,直接从数据库重新生成代理类。 (当然,在解决+构建对 SQL 文件的任何冲突更改之后) 极限版本:在每次自动构建期间执行此操作,而不仅仅是在合并时执行此操作。
I'm not super familiar with EF in particular, but I've had my fair share of issues with ultra verbose & fragile autogenerated code. In each case, the best answer on how to merge it was "don't." In your scenario that probably means one of two things:
1) Tighten your code promotion model so that EF code only flows in one direction. In other words, every conflict will be resolved as either "copy from source branch" (AcceptTheirs) or "keep target unchanged" (AcceptYours), and everyone should know which is which in advance. Most commonly, you'll want to AcceptTheirs when promoting newly tested code toward the stable nodes of the branch tree and AcceptYours when merging fixes back to unstable/development branches. (If there is >1 development branch then you'll want to partition things so that only EF code owned by the team working in a given branch follows the latter rule. Anything they're not intentionally altering should be overwritten by other teams' code flowing from the integration branch, using AcceptTheirs if necessary.)
"Merge down, copy up"
2) Literally do not merge them; exclude EF code from the process entirely. When integrating branches requires changes to the database and/or ORM, regenerate the proxy classes directly from the database. (after resolving + building any conflicting changes to your SQL files, of course) Extreme version: do this during every automated build, not just when merging.