¿Cómo configura DbContext al crear migraciones en Entity Framework Core?

.net-core c# dbcontext dependency-injection entity-framework-core

Pregunta

¿Hay alguna forma de que la inyección de dependencia se pueda configurar / arrancar al usar los comandos de migración de Entity Framework?

Entity Framework Core admite la inyección de dependencias para DbContext subclases DbContext . Este mecanismo incluye permitir la configuración de acceso a datos fuera de DbContext .

Por ejemplo, lo siguiente configuraría EF para persistir en un servidor SQL utilizando una cadena de conexión recuperada de config.json

ServiceCollection services = ...

var configuration = new Configuration().AddJsonFile( "config.json" );
services.AddEntityFramework( configuration )
    .AddSqlServer()
    .AddDbContext<BillingDbContext>( config => config.UseSqlServer() );

Sin embargo, los comandos de migración no saben cómo ejecutar este código, por lo que Add-Migration fallará por falta de un proveedor o por falta de una cadena de conexión.

Se puede hacer que las migraciones funcionen anulando OnConfiguring dentro de la subclase DbContext para especificar el proveedor y la cadena de configuración, pero esto DbContext cuando se desea una configuración diferente en otro lugar. En última instancia, mantener mis comandos de migración y mi código trabajando ambos se vuelve indeseablemente complejo.

Nota: Mi DbContext vive en un ensamblaje diferente al punto de entrada que lo usa y mi solución tiene varios proyectos de inicio.

Respuesta aceptada

Como @bricelam comentó, esta funcionalidad aún no existe en Entity Framework 7. Esta funcionalidad faltante es rastreada por GitHub número aspnet / EntityFramework # 639

Mientras tanto, la solución más sencilla que encontré fue utilizar un estado global en lugar de problemas con la subclasificación. No suele ser mi primera opción de diseño, pero funciona bien por ahora.

En MyDbContext:

public static bool isMigration = true;

protected override void OnConfiguring( DbContextOptionsBuilder optionsBuilder )
{
    // TODO: This is messy, but needed for migrations.
    // See https://github.com/aspnet/EntityFramework/issues/639
    if ( isMigration )
    {
        optionsBuilder.UseSqlServer( "<Your Connection String Here>" );
    }
}

En Startup.ConfigureServices() .

public static bool isMigration = true;

protected override void OnConfiguring( DbContextOptionsBuilder optionsBuilder )
{
    // TODO: This is messy, but needed for migrations.
    // See https://github.com/aspnet/EntityFramework/issues/639
    if ( isMigration )
    {
        optionsBuilder.UseSqlServer( "<Your Connection String Here>" );
    }
}

(El código de configuración realmente vive en un Módulo Autofac en mi caso).


Respuesta popular

Utilizando IDbContextFactory<TContext>

Implemente esta interfaz para habilitar los servicios en tiempo de diseño para los tipos de contexto que no tienen un constructor público predeterminado. Los servicios en tiempo de diseño descubrirán automáticamente implementaciones de esta interfaz que se encuentran en el mismo ensamblaje que el contexto derivado.

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace MyProject
{
    public class BloggingContextFactory : IDbContextFactory<BloggingContext>
    {
        public BloggingContext Create()
        {
            var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
            optionsBuilder.UseSqlServer("connection_string");

            return new BloggingContext(optionsBuilder.Options);
        }
    }
}

más información: https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext

Si no está satisfecho con la cadena de conexión codificada, eche un vistazo a este artículo.




Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué