6

È possibile che l'iniezione delle dipendenze possa essere configurata/riavviata quando si utilizzano i comandi di migrazione di Entity Framework?Come si configura DbContext quando si creano migrazioni in Entity Framework Core?

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

Ad esempio, il seguente sarebbe configurare EF di persistere a un server SQL utilizzando una stringa di connessione recuperato 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 migrazioni non sanno eseguire questo codice in modo Add-Migration falliranno per mancanza di un provider o la mancanza di una stringa di connessione.

migrazioni può essere fatto per lavorare sovrascrivendo OnConfiguring all'interno del DbContext sottoclasse per specificare la stringa del provider e la configurazione, ma che si mette di mezzo, quando diversa configurazione si desidera altrove. In definitiva, mantenere i miei comandi di migrazione e il mio codice entrambi funzionanti diventa indesiderabilmente complesso.

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

+0

La figura è parte del problema [n. 639] (https://github.com/aspnet/EntityFramework/issues/639). In ASP.NET 5, chiameremo 'Startup.ConfigureServices()'. Secondo te, sarebbe meglio usare la stessa convenzione per progetti non-ASP.NET 5? – bricelam

+0

@bricelam Ora che ho sviluppato un po 'di sviluppo in ASP.NET 5 (utilizzo l'EF7 nell'applicazione .NET tradizionale), posso dire che la standardizzazione della classe 'Startup' mi suona bene. – vossad01

+0

Ho premuto per questo in [aspnet/Hosting n. 286] (https://github.com/aspnet/Hosting/issues/286), ma ho perso. La decisione era di avere diversi caricatori DbContext per diversi tipi di applicazione. Vedi [aspnet/EntityFramework # 2357] (https://github.com/aspnet/EntityFramework/issues/2357). – bricelam

risposta

3

Come @bricelam commentato questa funzionalità ancora non esiste in Entity Framework 7. Questa funzionalità mancante è monitorato da GitHub numero aspnet/EntityFramework#639

Nel frattempo, la soluzione più semplice che ho trovato era quella di utilizzare uno stato globale piuttosto che problemi con la sottoclasse. 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 in realtà vive in un modulo Autofac nel mio caso).

+0

È possibile verificare le proprietà di OpzioniBuilder.IsConfigured anziché il flag isMigration. –

0

So che questa è una domanda vecchia ma io uso il metodo onConfiguring e non ho questo problema

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
{ 
    optionsBuilder.UseSqlServer(Startup.Configuration.Get("Data:DefaultConnection:ConnectionString")); 
} 
+1

Grazie Pedro, a meno che qualcosa non sia cambiato, questo non funziona nella mia situazione. La classe 'Startup' utilizzata dalla mia applicazione non può essere referenziata nella sottoclasse' DbContext' perché vivono in diversi assembly. Fare questa configurazione qui e in 'Startup' non è compatibile. – vossad01

0

chiedo solo per un'istanza ed eseguire le migrazioni nei miei Startup.cs presentare

public void ConfigureServices(IServiceCollection services) 
    { 
     // ASPNet Core Identity 
     services.AddDbContext<RRIdentityDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("RRIdentityConnectionString"))); 

    } 

E poi in Configurare:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     var rrIdentityContext = app.ApplicationServices.GetService<RRIdentityDbContext>(); 
     rrIdentityContext.Database.Migrate(); 
    } 

Nota: non v'è alcun 'EnsureCreated' per il database. La migrazione dovrebbe crearlo se non esiste, anche se si suppone di capire le autorizzazioni che non conosco, così ho creato un database vuoto.

0

Per combinare le risposte sopra questo funziona per me

private readonly bool isMigration = false; 
public MyContext() 
{ 
    isMigration = true; 
} 

public MyContext(DbContextOptions<MyContext> options) : base(options) 
{ 

} 

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
{ 
    if (isMigration) 
    { 
     optionsBuilder.UseSqlServer("CONNECTION_STRING"); 
    } 
} 
0

Utilizzando IDbContextFactory<TContext>

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

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

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

Se non sei felice con la connessione stringa hard-coded, dare un'occhiata a this articolo.

Problemi correlati