Al momento attuale tutto il flusso Startup.cs
predefinito eseguito su ogni operazione relativa a db come drop db, aggiunta di migrazione, aggiornamento di db alle migrazioni, ecc.
Ho un codice di app specifico in Startup
che deve essere richiamato solo se l'applicazione viene eseguita per davvero. Quindi, come posso rilevare che la classe Startup
eseguita dalla migrazione o da un altro comando dotnet
relativo al database.
Bene, come già notato nel commento a una domanda, c'è un'interfaccia IDesignTimeDbContextFactory
che deve essere implementata per risolvere DbContext
in DbContext
di progettazione.
Potrebbe sembrare un po 'come questo:
public static class Programm{
...
public static IWebHost BuildWebHostDuringGen(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<StartupGen>() // <--- I'm just using different Startup child there where could be less complex code
.UseDefaultServiceProvider(options => options.ValidateScopes = false).Build();
}
}
public class DbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
public MyDbContex CreateDbContext(string[] args)
{
return Program.BuildWebHostDuringGen(args).Services.GetRequiredService<MyDbContext>();
}
}
Tuttavia, a causa di alcune ragioni non chiare (ho chiesto a ragazzi di Microsoft, ma non me lo spiegano) dotnet
attualmente su ogni operazione chiama implicitamente Programm.BuildWebHost
anche se è privato - questo è il motivo per cui il flusso standard eseguito ogni volta per il autore della domanda. Soluzione per questo - Rinomina Programm.BuildWebHost
a qualcos'altro, come InitWebHost
C'è un problema creato per questo, quindi forse sarà risolto nella versione 2.1 in futuro.
La documentazione è ancora un po 'oscura sul motivo per cui ciò si verifica. Devo ancora trovare una risposta concreta sul motivo per cui viene eseguito Startup.Configure
. Nel 2.0 si consiglia di spostare qualsiasi codice di migrazione / seeding su Program.Main
. Ecco un esempio di bricelam su Github .
public static IWebHost MigrateDatabase(this IWebHost webHost)
{
using (var scope = webHost.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var db = services.GetRequiredService<ApplicationDbContext>();
db.Database.Migrate();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while migrating the database.");
}
}
return webHost;
}
public static void Main(string[] args)
{
BuildWebHost(args)
.MigrateDatabase()
.Run();
}