Estoy trabajando con una base de datos de SQL Server con más de 1000 tablas, otros cientos de vistas y varios miles de procedimientos almacenados. Estamos buscando comenzar a usar Entity Framework para nuestros proyectos más nuevos, y estamos trabajando en nuestra estrategia para hacerlo. Lo que me preocupa es la mejor manera de dividir las tablas en diferentes modelos (EDMX o DbContext si vamos a codificar primero). Puedo pensar en algunas estrategias desde el principio:
- Dividido por esquema
Tenemos nuestras tablas divididas en probablemente una docena de esquemas. Podríamos hacer un modelo por esquema. Sin embargo, esto no es perfecto, porque dbo todavía termina siendo muy grande, con más de 500 tablas / vistas. Otro problema es que ciertas unidades de trabajo terminarán teniendo que realizar transacciones que abarcan múltiples modelos, lo que se suma a la complejidad, aunque supongo que EF lo hace bastante sencillo. - Dividir por intención
En lugar de preocuparse por los esquemas, divida los modelos por intención. Por lo tanto, tendremos diferentes modelos para cada aplicación, proyecto, módulo o pantalla, dependiendo de qué tan granulares queramos obtener. El problema que veo con esto es que hay ciertas tablas que inevitablemente deben usarse en todos los casos, como User o AuditHistory. ¿Los agregamos a cada modelo (creo que viola DRY), o son aquellos en un modelo separado que es utilizado por cada proyecto? - No se divida en absoluto: un modelo gigante
Esto es obviamente simple desde una perspectiva de desarrollo, pero desde mi investigación y mi intuición parece que podría funcionar terriblemente, tanto en tiempo de diseño, tiempo de compilación y posiblemente tiempo de ejecución.
¿Cuál es la mejor práctica para usar EF en una base de datos tan grande? Específicamente, ¿qué estrategias utilizan las personas para diseñar modelos contra este volumen de objetos DB? ¿Hay opciones en las que no estoy pensando que funcionen mejor que las que tengo arriba?
Además, ¿es esto un problema en otros ORM como NHibernate? Si es así, ¿han encontrado alguna solución mejor que EF?
fuente
Respuestas:
Personalmente, he intentado hacer un gran esquema para todas mis entidades en un proyecto bastante complejo pero pequeño (~ 300 tablas). Teníamos una base de datos extremadamente normalizada (normalización de quinta forma (lo digo de manera general)) con muchas relaciones "muchas a muchas" y una aplicación extrema de la integridad referencial.
También utilizamos una estrategia de "instancia única por solicitud" que tampoco estoy convencido de que haya ayudado.
Cuando se realizaban listas simples, razonablemente planas "explícitamente definidas", las búsquedas y los ajustes de rendimiento generalmente eran aceptables. Pero cuando comenzamos a profundizar en las relaciones profundas, el rendimiento pareció tener drásticas caídas. En comparación con un proceso almacenado en este caso, no hubo comparación (por supuesto). Estoy seguro de que podríamos haber modificado la base del código aquí y allá para mejorar el rendimiento, sin embargo, en este caso solo necesitábamos un aumento del rendimiento sin análisis debido a limitaciones de tiempo, y volvimos al proceso almacenado (aún lo mapeé a través de EF, porque EF proporcionó resultados fuertemente tipados), solo necesitábamos eso como un retroceso en algunas áreas. Cuando tuvimos que recorrer toda la base de datos para crear una colección (usando .include () sin disimulo), el rendimiento fue notablemente degradante, pero tal vez estábamos pidiendo demasiado ...
Entonces, según mi experiencia, recomendaría crear un .edmx separado por intento. Solo genere lo que usará en función del alcance de esa necesidad. Es posible que tenga algunos archivos .edmx de ámbito más pequeño para tareas específicas, y luego algunos grandes donde necesite atravesar relaciones complejas para construir objetos. No estoy seguro de dónde está ese lugar mágico, pero estoy seguro de que hay uno ... jaja ...
Honestamente, sin embargo, aparte de algunos escollos que vimos venir (travesía compleja), el enorme .edmx funcionó bien desde una perspectiva "funcional". Pero tendrá que estar atento a la magia de "reparación" que hace el contexto detrás de la escena si no la deshabilita explícitamente. Además de mantener el .edmx sincronizado cuando se realizan cambios en la base de datos ... a veces era más fácil borrar toda la superficie y volver a crear las entidades, lo que tomó como 3 minutos, por lo que no fue un gran problema.
Todo esto fue con EntityFramework 4.1. También me interesaría saber sobre su elección final y su experiencia.
Y con respecto a su pregunta sobre nHibernate, esa es una pregunta de lata de gusanos, en mi opinión, ladrará a ambos lados de la cerca ... Escucho que mucha gente golpea a EF por golpear sin tener que pasar por el desafíos y comprensión de los matices exclusivos de EF en sí ... y aunque nunca he usado nHibernate en la producción, en general, si tiene que crear manual y explícitamente cosas como mapeos, obtendrá un control más finito si puedo arrastrar y soltar, generar y comenzar a CRUD y hacer consultas usando LINQ, podría dar una mierda sobre la granularidad.
Espero que esto ayude.
fuente
Permítanme comenzar con una simple aclaración: no tengo experiencia con una base de datos tan grande, por lo que el resto de mi respuesta no se basa en el ejemplo del mundo real.
Entonces tiene una base de datos GRANDE y quiere usarla con ORM / EF. Yo iría con la segunda opción. Aquí está mi explicación simple por qué:
fuente
Diría que no puede decidir este tipo de preguntas desde una perspectiva técnica. Le recomendaría que construya su arquitectura en función de sus casos de uso (historias de usuarios, etc.). Primero encuentre sus objetos comerciales. Un objeto de entidad no es por defecto un objeto comercial. Típicamente tendrá un objeto comercial frente a los objetos de la entidad. Luego, puede decidir de forma incremental lo que realmente necesita, en función de los requisitos del usuario.
"Un buen arquitecto maximiza el número de decisiones que no se toman". Robert C. Martin
http://cleancoder.posterous.com/architecture-deference
fuente
Utilizo un enfoque híbrido: EF maneja las cosas de OLTP, mientras que las operaciones pesadas, como las inserciones por lotes, las actualizaciones masivas, las consultas de informes, etc., son manejadas por Stored Procs. También facilita la ruta de migración si no está haciendo una reescritura completa de su capa de datos de una sola vez.
fuente