Dispongo di un'applicazione Entity Framework Core + ASP.NET Core e all'avvio dell'applicazione desidero assicurarmi che il database sia stato creato, e alla fine (una volta eseguite le migrazioni) voglio assicurarmi che vengano eseguiti anche quelli.
Inizialmente inserisco Database.EnsureCreated()
nel costruttore del mio DbContext
ma sembra che venga eseguito ogni volta che un utente DbContext
la mia applicazione da quando una nuova istanza di DbContext
viene creata ogni volta.
Ho provato a inserirlo nel mio codice di avvio, ma ho bisogno di un'istanza del mio DbContext
per farlo e non è chiaro come esattamente ottenerne uno. Sto configurando EF in questo modo:
serviceCollection.AddEntityFramework()
.AddSqlServer()
.AddDbContext<Models.MyContext>(options => options.UseSqlServer(...));
Non vedo un modo per ottenere un'istanza di DbContext dalla raccolta di servizi e non vedo alcun singleton appropriato per iniettare un DbContext in modo da poter eseguire un'inizializzazione di una sola volta.
Quindi qual è il posto migliore per garantire che un codice relativo al mio DbContext venga chiamato una volta per esecuzione dell'applicazione?
Al momento della stesura di questo documento, non esiste un posto "corretto" per eseguire il codice all'avvio dell'applicazione in modo che venga eseguito nell'ambito della richiesta (consultare https://github.com/aspnet/Hosting/issues/373 ).
Per ora, la soluzione alternativa è eseguire le seguenti operazioni, ma non funzionerà in scenari multi-applicazione più complessi (consultare https://github.com/aspnet/EntityFramework/issues/3070#issuecomment-142752126 )
public class Startup
{
...
public void Configure(IApplicationBuilder applicationBuilder, ...)
{
...
// NOTE: this must go at the end of Configure
var serviceScopeFactory = applicationBuilder.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
using (var serviceScope = serviceScopeFactory.CreateScope())
{
var dbContext = serviceScope.ServiceProvider.GetService<MyDbContext>();
dbContext.Database.EnsureCreated();
}
}
}