Entity Framework Merge Nightmare

后端 未结 5 1675
说谎
说谎 2020-12-04 18:36

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 conflic

相关标签:
5条回答
  • 2020-12-04 18:36

    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).

    0 讨论(0)
  • 2020-12-04 18:38

    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.

    <?xml version="1.0" encoding="utf-8"?>
    <edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
      <!-- EF Runtime content -->
      <edmx:Runtime>
      <!-- Removed for brevity's sake only!-->
      </edmx:Runtime>
      <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
      <Designer xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
        <Connection>
          <DesignerInfoPropertySet>
            <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
          </DesignerInfoPropertySet>
        </Connection>
        <Options>
          <DesignerInfoPropertySet>
            <DesignerProperty Name="ValidateOnBuild" Value="true" />
            <DesignerProperty Name="EnablePluralization" Value="True" />
            <DesignerProperty Name="IncludeForeignKeysInModel" Value="True" />
          </DesignerInfoPropertySet>
        </Options>
        <!-- Diagram content (shape and connector positions) -->
        <Diagrams>
        </Diagrams>
      </Designer>
    </edmx:Edmx>
    

    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.

    0 讨论(0)
  • 2020-12-04 18:44

    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. :)

    0 讨论(0)
  • 2020-12-04 18:47

    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.

    0 讨论(0)
  • 2020-12-04 19:01

    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.)

                   /- [...]
                   /- v1.1
              /- Release
    + Integration - Dev1 - Dev2 - [...]

    "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.

    0 讨论(0)
提交回复
热议问题