Entity Framework Merge Nightmare
Мы приняли платформу Entity Framework, и мы обнаруживаем, что когда несколько человек делают изолированные изменения в своих отдельных ветвях управления источниками, возникают массовые конфликты, когда они объединяются в слияние, приводя к сломанным файлам моделей.
Мы склоняемся в сторону форсирования эксклюзивных проверок в файле, но я бы хотел этого избежать.
Мой вопрос...
Есть ли лучший инструмент сравнения, который бы справился с этим лучше, или есть другой подход, который мы могли бы предпринять?
Ищите что-то, что доказано, если это возможно.
НОВОЕ ОБНОВЛЕНИЕ:
Для тех из вас, кто сталкивается с этим вопросом, он основан на старой EF. Я предлагаю перейти к использованию DbContext над EDMX. Здесь много информации об этом. Простота базы данных сначала или кода сначала намного перевешивает потерю дизайнера, на мой взгляд.
UPDATE:
Мы решили эту проблему, принудительно исключив изменения в файл. Добавив этот процесс, мы полностью устранили любые проблемы. Хотя это было не идеальное решение, оно было самым надежным и простым в реализации.
Ответы
Ответ 1
Craig Stuntz неплохо объясняет, что это связанный с дизайнером xml (позиции сущностей и ассоциаций и т.д. на поверхности дизайна) что вызывает большинство проблем здесь. Однако разрешение конфликта в элементе edmx:Runtime
очень доступно.
Лучшая стратегия борьбы с конфликтами в XML-дизайнере заключается в том, чтобы обойти их вообще, жертвуя любым настраиваемым макетом и возвращаясь к макету по умолчанию.
Хитрость заключается в удалении всего содержимого элемента <Diagrams>
. Дизайнер откроется без каких-либо проблем и применит макет по умолчанию.
Ниже приведен пример файла EDMX, который будет открыт по умолчанию. Обратите внимание, что содержимое элемента <edmx:Runtime>
также было удалено, но это было только ради краткости - оно не является частью решения.
<?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 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>
Обратите внимание, что применяемый здесь макет по умолчанию не соответствует тому, который появляется, когда вы выбираете Diagram | Layout Diagram
из контекстного меню конструктора, что я и ожидал.
Обновление: По сравнению с Entity Framework 5, это становится немного проще. поддержка нескольких диаграмм добавила туда разгружает диаграмму, связанную с xml, для разделения файлов. Обратите внимание, что у меня все еще были некоторые старые связанные диаграммы теги в файле edmx, в котором произошел ряд обновлений Entity Framework. Я просто удалил тег с именем Diagrams (включая дочерние элементы) из файла edmx.
Ответ 2
Существуют некоторые стратегии для работы с крупными моделями Entity Framework в этой статье. Вы могли бы использовать их. Тем не менее, я обнаружил, что большая часть боли с регенерацией EDMX происходит из-за изменений, сделанных путем перетаскивания на GUI-дизайнера. С другой стороны, выполнение "Обновить модель из базы данных" или через окно свойств имеет тенденцию к внесению изменений довольно разумным образом и, как правило, сложно слить.
Самая большая проблема, насколько я вижу, заключается в том, что информация о макете для модели визуальных объектов в моделях концептуального/сопоставления/хранения находится в одном файле. Другими словами, проблема заключается не столько в размере самого файла или изменениях, внесенных в модель сущности, сколько в оптовой перестановке, которая возникает при перетаскивании объекта в GUI-дизайнере. Я желаю, чтобы дизайн дизайнера GUI и модели концептуального/картографического/хранилища были в разных файлах. Я считаю, что это устранит большую часть боли слиянием изменений в модели.
Следовательно, у нас есть полуофициальная политика не вносить изменения в графический макет модели. Это не большая потеря, потому что, когда у вас в вашей модели более пары десятков сущностей, дизайнер GUI с одной страницей на самом деле не очень полезен. И это, безусловно, делает слияния намного проще.
Версия 4 Entity Framework будет иметь возможность делать генерации артефактов на основе шаблонов T4. Я не эксперт, но может быть возможно уговорить информацию макета GUI в другой файл с использованием шаблона T4.
Ответ 3
Как вы сказали, одним из вариантов является блокировка файла.
Другой возможный вариант - перенаправить все изменения модели через одного человека в команде.
Другой вариант - разбить файл на более мелкие файлы (например, один на класс), возможно, оставив после себя некоторую поддержку дизайнера в этом процессе.
Другим вариантом является создание собственного процесса, потенциально использующего XSLT для преобразования EDMX файла, но я не уверен точно, как это будет выглядеть: файл designer.cs является очень сложным для объединения.
Другой вариант - рассмотреть другой ORM.
Я не уверен, что они что-то делают, чтобы улучшить это в следующей версии EF. Бросать столько данных в один файл не означает масштабируемости любого вида (все же LinqToSql делает то же самое - в этом случае Damien Guard создал несколько шаблонов T4, чтобы разбить файл отдельно, не уверен, что существует нечто подобное для EF).
Ответ 4
Я не очень хорошо знаком с EF, но у меня была своя доля проблем с ультра-подробным и хрупким автогенерированным кодом. В каждом случае лучший ответ о том, как слить его, - "не надо". В вашем сценарии это, вероятно, означает одну из двух вещей:
1) Затяните модель продвижения кода, чтобы код EF переходил только в одном направлении. Другими словами, каждый конфликт будет разрешен либо как "копия из ветки источника" (AcceptTheirs), либо "сохранить цель без изменений" (AcceptYours), и каждый должен знать, что это заранее. Чаще всего вы захотите AcceptTheirs при продвижении вновь проверенного кода к стабильным узлам дерева ветвей и AcceptYours при объединении исправлений обратно в ветки неустойчивой/развития. (Если есть > 1 ветвь развития, тогда вы захотите разделить вещи, чтобы только код EF, принадлежащий команде, работающей в данной ветки, соответствовал последнему правилу. Все, что они не намеренно изменяют, должно быть перезаписано кодом других команд вытекающих из ветки интеграции, используя AcceptTheirs, если это необходимо.)
/- [...]
/- v1.1
/- Release
+ Integration
- Dev1
- Dev2
- [...]
" Слить, скопировать
2) Буквально не сливайте их; полностью исключить код EF из процесса. Когда интеграция ветвей требует изменений в базе данных и/или ORM, регенерируйте прокси-классы непосредственно из базы данных. (после разрешения + создания любых противоречивых изменений в ваших файлах SQL, конечно). Экстремальная версия: делать это во время каждой автоматической сборки, а не только при слиянии.
Ответ 5
Я действительно пытался убедить свою компанию пойти в Code First именно по этой причине и, к сожалению, был закрыт. Им нравится возможность пользоваться дизайнером. К сожалению, я столкнулся с проблемами в нашем последнем производстве, где одна из наших служб WCF имеет около 10 конечных точек в ней для поддержки нескольких потребителей, и в процессе слияния в CS-разделе файла EDMX было несколько дублированных записей.
В моих личных проектах я использую только Code First. Для меня это по той же причине я предпочитаю ручной по автоматической коробке передач. Конечно, дизайнеру модели может быть проще (иногда, как мы уже говорили), но с Code First вы получаете гораздо более прямой контроль над тем, что происходит. Также как механическая коробка передач.:)