目前,在每个与数据库相关的操作上执行所有默认Startup.cs
流,例如删除数据库,添加迁移,更新数据库到迁移等等。
我在Startup
中有大量特定于应用程序的代码,只有在应用程序运行真实时才需要调用它。那么如何检测Startup
类是从迁移还是其他与数据库相关的dotnet
命令运行的。
答案 0 :(得分:7)
好吧,因为在对问题的评论中已经注意到,在设计时需要实施IDesignTimeDbContextFactory
接口以解析DbContext
。
看起来有点像这样:
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>();
}
}
然而,由于一些不明原因(我问微软的人,但是他们没有向我解释这一点)dotnet
目前在每个操作上隐含地调用Programm.BuildWebHost
即使它是私有的 - 这是每次为问题的作者执行标准流程的原因。解决方法 - 重命名 Programm.BuildWebHost
到其他地方,例如InitWebHost
有一个issue created,所以也许它将在2.1版本中解决。
答案 1 :(得分:2)
documentation对于为什么会发生这种情况仍然有点不清楚。我还没有找到任何具体的答案,为什么它运行Startup.Configure
。在2.0中,recommend将任何迁移/种子代码移至Program.Main
。以下是bricelam Github上的https://docs.angularjs.org/guide/interpolation示例。
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();
}