Come si configura DbContext durante la creazione di migrazioni in Entity Framework Core?

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

Domanda

È possibile che l'integrazione delle dipendenze possa essere configurata / riavviata quando si utilizzano i comandi di migrazione di Entity Framework?

Entity Framework Core supporta l' DbContext dipendenze per DbContext sottoclassi DbContext . Questo meccanismo include la possibilità di configurare l'accesso ai dati al di fuori di DbContext .

Ad esempio, quanto segue configurerebbe EF come persistente su un server SQL utilizzando una stringa di connessione recuperata da config.json

ServiceCollection services = ...

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

Tuttavia, i comandi di migrazione non sanno di eseguire questo codice in modo che Add-Migration fallisca per mancanza di un provider o per mancanza di una stringa di connessione.

Le migrazioni possono essere fatte funzionare sovrascrivendo OnConfiguring all'interno della sottoclasse DbContext per specificare il provider e la stringa di configurazione, ma questo DbContext quando si desidera una diversa configurazione altrove. In definitiva, mantenere i miei comandi di migrazione e il mio codice entrambi funzionanti diventa indesiderabilmente complesso.

Nota: My DbContext vive in un assembly diverso rispetto al punto di ingresso che lo utilizza e la mia soluzione ha più progetti di avvio.

Risposta accettata

Come @bricelam ha commentato questa funzionalità non esiste ancora in Entity Framework 7. Questa funzionalità mancante è tracciata dal problema di GitHub aspnet / EntityFramework # 639

Nel frattempo, la soluzione più semplice che ho trovato è stata quella di utilizzare uno stato globale anziché complicare le sottoclassi. Di solito non è la mia prima scelta di design, ma per ora funziona bene.

In 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>" );
    }
}

In Startup.ConfigureServices() .

public IServiceProvider ConfigureServices( IServiceCollection services )
{
    MyContext.isMigration = false;

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

(Il codice di configurazione risiede in un modulo Autofac nel mio caso.)


Risposta popolare

Utilizzo di IDbContextFactory<TContext>

Implementare questa interfaccia per abilitare i servizi in fase di progettazione per i tipi di contesto che non dispongono di un costruttore pubblico predefinito. I servizi in fase di progettazione scopriranno automaticamente le implementazioni di questa interfaccia che si trovano nello stesso assieme del contesto derivato.

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);
        }
    }
}

maggiori informazioni: https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext

Se non sei soddisfatto della stringa di connessione hard-coded, dai un'occhiata a questo articolo.




Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché