Saltar al contenido

Entity Framework: una base de datos, varios DbContexts. ¿Es una mala idea?

Tenemos la solución a esta escollo, o por lo menos eso pensamos. Si presentas preguntas dínoslo y con placer te ayudaremos

Solución:

Puede tener varios contextos para una sola base de datos. Puede ser útil, por ejemplo, si su base de datos contiene varios esquemas de base de datos y desea manejar cada uno de ellos como un área autónoma separada.

El problema es cuando desea usar el código primero para crear su base de datos; solo un contexto único en su aplicación puede hacerlo. El truco para esto suele ser un contexto adicional que contiene todas sus entidades y que se usa solo para la creación de bases de datos. Los contextos de su aplicación real que contienen solo subconjuntos de sus entidades deben tener el inicializador de base de datos configurado en null.

Hay otros problemas que verá al usar múltiples tipos de contexto, por ejemplo, tipos de entidades compartidas y su paso de un contexto a otro, etc. Generalmente es posible, puede hacer que su diseño sea mucho más limpio y separar diferentes áreas funcionales, pero tiene su costos en complejidad adicional.

Escribí esta respuesta hace unos cuatro años y mi opinión no ha cambiado. Pero desde entonces ha habido avances significativos en el frente de los microservicios. Agregué notas específicas de microservicios al final …

Sopesaré la idea, con la experiencia del mundo real para respaldar mi voto.

Me llevaron a una gran aplicación que tenía cinco contextos para una sola base de datos. Al final, terminamos eliminando todos los contextos excepto uno, volviendo a un solo contexto.

Al principio, la idea de contextos múltiples parece una buena idea. Podemos separar nuestro acceso a los datos en dominios y proporcionar varios contextos limpios y ligeros. Suena como DDD, ¿verdad? Esto simplificaría nuestro acceso a los datos. Otro argumento es a favor del rendimiento en el sentido de que solo accedemos al contexto que necesitamos.

Pero en la práctica, a medida que crecía nuestra aplicación, muchas de nuestras tablas compartían relaciones en nuestros diversos contextos. Por ejemplo, las consultas a la tabla A en el contexto 1 también requerían unirse a la tabla B en el contexto 2.

Esto nos dejó con un par de malas opciones. Podríamos duplicar las tablas en los distintos contextos. Intentamos esto. Esto creó varios problemas de mapeo, incluida una restricción EF que requiere que cada entidad tenga un nombre único. Así que terminamos con entidades llamadas Person1 y Person2 en los diferentes contextos. Se podría argumentar que este fue un diseño deficiente de nuestra parte, pero a pesar de nuestros mejores esfuerzos, así es como nuestra aplicación realmente creció en el mundo real.

También intentamos consultar ambos contextos para obtener los datos que necesitábamos. Por ejemplo, nuestra lógica empresarial consultaría la mitad de lo que necesitaba del contexto 1 y la otra mitad del contexto 2. Esto tenía algunos problemas importantes. En lugar de realizar una consulta en un solo contexto, tuvimos que realizar múltiples consultas en diferentes contextos. Esto tiene una verdadera penalización de rendimiento.

Al final, la buena noticia es que fue fácil eliminar los múltiples contextos. El contexto está destinado a ser un objeto ligero. Así que no creo que el desempeño sea un buen argumento para múltiples contextos. En casi todos los casos, creo que un solo contexto es más simple, menos complejo y probablemente funcionará mejor, y no tendrá que implementar un montón de soluciones para que funcione.

Pensé en una situación en la que múltiples contextos podrían ser útiles. Se podría usar un contexto separado para solucionar un problema físico con la base de datos en la que en realidad contiene más de un dominio. Idealmente, un contexto sería uno a uno para un dominio, que sería uno a uno para una base de datos. En otras palabras, si un conjunto de tablas no está relacionado de ninguna manera con las otras tablas en una base de datos determinada, probablemente deberían extraerse en una base de datos separada. Me doy cuenta de que esto no siempre es práctico. Pero si un conjunto de tablas es tan diferente que se sentiría cómodo separándolos en una base de datos separada (pero elige no hacerlo), entonces podría ver el caso de usar un contexto separado, pero solo porque en realidad hay dos dominios separados.

En cuanto a los microservicios, todavía tiene sentido un contexto único. Sin embargo, para los microservicios, cada servicio tendría su propio contexto que incluye solo las tablas de la base de datos relevantes para ese servicio. En otras palabras, si el servicio x accede a las tablas 1 y 2, y el servicio y accede a las tablas 3 y 4, cada servicio tendría su propio contexto único que incluye tablas específicas para ese servicio.

Me interesan tus pensamientos.

Distinguir contextos estableciendo el esquema predeterminado

En EF6 puede tener varios contextos, solo especifique el nombre del esquema de base de datos predeterminado en el OnModelCreating método de ti DbContext clase derivada (donde está la configuración de Fluent-API). Esto funcionará en EF6:

public partial class CustomerModel : DbContext
   
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        modelBuilder.HasDefaultSchema("Customer");

        // Fluent API configuration
       

Este ejemplo utilizará “Cliente” como prefix para las tablas de su base de datos (en lugar de “dbo”). Más importante aún, también prefix los __MigrationHistory mesa (s), p. ej. Customer.__MigrationHistory. Entonces puedes tener más de uno __MigrationHistory tabla en una sola base de datos, una para cada contexto. Por lo tanto, los cambios que realice para un contexto no afectarán al otro.

Al agregar la migración, especifique el nombre completo de su clase de configuración (derivado de DbMigrationsConfiguration) como parámetro en el add-migration mando:

add-migration NAME_OF_MIGRATION -ConfigurationTypeName FULLY_QUALIFIED_NAME_OF_CONFIGURATION_CLASS

Una breve palabra sobre el contexto. key

Según este artículo de MSDN “Capítulo – Múltiples modelos dirigidos a la misma base de datos”, EF 6 probablemente manejaría la situación incluso si solo uno MigrationHistory existía una tabla, porque en la tabla hay una columna ContextKey para distinguir las migraciones.

Sin embargo, prefiero tener más de uno. MigrationHistory tabla especificando el esquema predeterminado como se explicó anteriormente.

Usar carpetas de migración independientes

En tal escenario, es posible que también desee trabajar con diferentes carpetas de “Migración” en su proyecto. Puede configurar su DbMigrationsConfiguration clase derivada en consecuencia utilizando el MigrationsDirectory propiedad:

internal sealed class ConfigurationA : DbMigrationsConfiguration

    public ConfigurationA()
    
        AutomaticMigrationsEnabled = false;
        MigrationsDirectory = @"MigrationsModelA";
    


internal sealed class ConfigurationB : DbMigrationsConfiguration

    public ConfigurationB()
    
        AutomaticMigrationsEnabled = false;
        MigrationsDirectory = @"MigrationsModelB";
    

Resumen

Con todo, puede decir que todo está claramente separado: contextos, carpetas de migración en el proyecto y tablas en la base de datos.

Elegiría una solución de este tipo, si hay grupos de entidades que son parte de un tema más grande, pero no están relacionadas (a través de keys) a otro.

Si los grupos de entidades no tuvieran nada que hacer entre sí, crearía una base de datos separada para cada uno de ellos y también accedería a ellos en diferentes proyectos, probablemente con un solo contexto en cada proyecto.

Comentarios y puntuaciones

Si te ha resultado de utilidad nuestro post, sería de mucha ayuda si lo compartes con otros entusiastas de la programación así contrubuyes a difundir este contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *