Pesadilla de fusión de Entity Framework


Hemos adoptado Entity Framework y estamos encontrando que cuando varias personas hacen cambios aislados en sus ramas de control de código fuente individuales, hay conflictos masivos cuando se unen en una fusión, lo que resulta en archivos de modelo rotos.

Nos inclinamos en la dirección de forzar salidas exclusivas en el archivo, pero me gustaría evitar eso.

Mi pregunta es...

¿Hay una mejor herramienta de comparación que maneje esto mejor, o hay otro enfoque podríamos tomar?

Buscando algo que esté probado si es posible.

NUEVA ACTUALIZACIÓN: Para aquellos de ustedes que se encuentran con esta pregunta, se basa en la antigua EF. Sugiero pasar a usar DbContext sobre EDMX. Hay un montón de información aquí en lo que al respecto. La simplicidad de Database first o Code first supera con creces la pérdida del diseñador en mi opinión.

ACTUALIZACIÓN: Resolvimos este problema forzando cambios exclusivos en el archivo. Añadiendo este proceso eliminamos completamente cualquier problema. Si bien esta no era la solución ideal, era la más confiable y fácil de implementar.

Author: ctorx, 2009-09-16

5 answers

Craig Stuntz hace un buen trabajo explicando que es el xml relacionado con el diseñador (las posiciones de entidades y asociaciones, etc. en la superficie de diseño) el que causa la mayoría de los problemas aquí. Sin embargo, la resolución de conflictos dentro del elemento edmx:Runtime es muy factible.

La mejor estrategia para tratar los conflictos en el xml relacionado con el diseñador es omitirlos por completo sacrificando cualquier diseño personalizado y volviendo a un diseño predeterminado.

El truco es elimina todo el contenido del elemento <Diagrams>. El diseñador se abrirá sin ningún problema y aplicará un diseño predeterminado.

El siguiente es un ejemplo de un archivo EDMX que se abrirá con un diseño predeterminado. Tenga en cuenta que el contenido del elemento <edmx:Runtime> también se eliminó, sin embargo, esto fue solo por razones de brevedad, no es parte de la solución.

<?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>

Tenga en cuenta que el diseño predeterminado que se aplica aquí no coincide con el que resulta cuando selecciona Diagram | Layout Diagram de la menú contextual del diseñador que es lo que yo hubiera esperado.

Actualización: A partir de Entity Framework 5, esto se vuelve un poco más fácil. El multiple diagram support agregado allí descarga el xml relacionado con el diagrama en archivos separados. Tenga en cuenta que todavía tenía algunas etiquetas antiguas relacionadas con diagramas en un archivo edmx que había experimentado una serie de actualizaciones de Entity Framework. Simplemente eliminé la etiqueta llamada Diagramas (incluidos los hijos) del archivo edmx.

 13
Author: Scott Munro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-03 08:50:59

Hay algunas estrategias para tratar con modelos de large Entity Framework en este artículo. Podrías considerar usarlas. Sin embargo, he encontrado que la mayor parte del dolor con la regeneración de la EDMX proviene de los cambios realizados a través de arrastrar y soltar en el diseñador de la interfaz gráfica de usuario. Por otro lado, hacer Actualizar el Modelo desde la Base de datos o a través de la ventana de propiedades tiende a hacer cambios de una manera bastante sensata, y no tiende a ser difícil de combinar.

El mayor problema, como por lo que puedo ver, es que la información de diseño para el modelo de objeto visual en los modelos conceptuales/mapping/storage están en el mismo archivo. En otras palabras, el problema no es tanto el tamaño del archivo en sí o los cambios realizados en el modelo de entidad en sí, sino la reorganización general que ocurre cuando arrastra y suelta un objeto en el diseñador de la interfaz gráfica de usuario. Desearía que el diseño del diseñador gráfico y los modelos conceptuales / de mapeo / almacenamiento estuvieran en archivos diferentes. Creo que esto eliminaría la mayor parte de el dolor con la fusión de los cambios en el modelo.

Por lo tanto, tenemos una política semioficial de no hacer cambios en el diseño gráfico del modelo. Esto no es una gran pérdida, porque cuando tiene más de un par de docenas de entidades en su modelo, el diseñador de GUI de una sola página no es realmente útil de todos modos. Y ciertamente hace que las fusiones sean mucho más fáciles.

La versión 4 de Entity Framework tendrá la opción de generar artefactos basados en plantillas T4. No soy un experto, pero puede ser posible coaxir la información de diseño de la GUI en un archivo diferente utilizando una plantilla T4.

 4
Author: Craig Stuntz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-17 13:52:18

Como ha dicho, una opción es bloquear el archivo.

Otra opción posible es enrutar todos los cambios del modelo a través de un individuo en el equipo.

Otra opción es dividir el archivo en archivos más pequeños (como uno por clase), posiblemente dejando algo de soporte de diseñador en el proceso.

Otra opción es crear su propio proceso, potencialmente usando XSLT para transformar el archivo EDMX, pero no estoy seguro exactamente cómo se vería esto, el diseñador.el archivo cs es el enorme difícil de fusionar uno.

Otra opción es considerar un OR diferente.

No estoy seguro de si están haciendo algo para mejorar esto en la próxima versión de EF. Lanzar esa cantidad de datos en un solo archivo no implica escalabilidad de ningún tipo (Sin embargo, LinqToSql hace lo mismo - En ese caso Damien Guard creó algunas plantillas T4 para separar el archivo, no estoy seguro de si existe algo similar para EF).

 3
Author: Michael Maddox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-16 18:21:27

En realidad traté de convencer a mi empresa para ir al Código Primero por esta misma razón, y fue cerrado, por desgracia. Les gusta poder usar al diseñador. Desafortunadamente, me encontré con problemas en nuestro último despliegue de producción donde uno de nuestros servicios WCF tiene alrededor de 10 puntos finales para soportar múltiples consumidores, y en el proceso de fusión, hubo varias entradas duplicadas en la sección C-S del archivo EDMX.

En mis proyectos personales, estoy usando Código Primero exclusivamente. A yo, es la misma razón por la que prefiero la transmisión manual sobre la automática. Claro, el diseñador del modelo puede ser más fácil (a veces, como hemos discutido), pero con el código Primero, obtienes un control mucho más directo de lo que está pasando. Como una transmisión manual. :)

 1
Author: Jamie Nordmeyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-20 15:19:47

No estoy muy familiarizado con EF en particular, pero he tenido mi parte justa de problemas con el código autogenerado ultra detallado y frágil. En cada caso, la mejor respuesta sobre cómo fusionarlo fue "no". En su escenario eso probablemente significa una de dos cosas:

1) Ajuste su modelo de promoción de código para que el código EF solo fluya en una dirección. En otras palabras, cada conflicto se resolverá como "copy from source branch" (AcceptTheirs) o "keep target unchanged" (AcceptYours), y todo el mundo debe saber cuál es cuál de antemano. Lo más común es que quieras aceptar Theirs cuando promociones código recién probado hacia los nodos estables del árbol de ramas y aceptar Theirs cuando combines correcciones a ramas inestables/de desarrollo. (Si hay > 1 rama de desarrollo, entonces querrá particionar las cosas para que solo el código EF propiedad del equipo que trabaja en una rama dada siga la última regla. Cualquier cosa que no estén alterando intencionalmente debe ser sobrescrita por el código de otros equipos fluyendo desde la rama de integración, usando AcceptTheirs si es necesario.)

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

"Merge down, copy up"

2) Literalmente no los combine; excluya el código EF del proceso por completo. Cuando la integración de ramas requiere cambios en la base de datos y/o OR, regenere las clases proxy directamente desde la base de datos. (después de resolver + compilar cualquier cambio conflictivo en sus archivos SQL, por supuesto) Versión extrema: haga esto durante cada compilación automatizada, no solo cuando fusionar.

 1
Author: Richard Berg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-03 08:54:32