Asp.Net 核心 2.0:检测从迁移或其他 ef 操作调用的启动 class
Asp.Net core 2.0: Detect Startup class invoked from migration or other ef operation
目前,所有默认 Startup.cs
流程在每个与数据库相关的操作上执行,例如删除数据库、添加迁移、将数据库更新为迁移等
我在 Startup
中有大量特定于应用程序的代码,仅当应用程序 运行 真实时才需要调用这些代码。那么我如何从迁移或其他与数据库相关的 dotnet
命令中检测到 Startup
class 运行。
documentation is still a bit unclear as to why this occurs. I've yet to find any concrete answer as to why it runs Startup.Configure
. In 2.0 it's recommend to move any migration/seeding code to Program.Main
. Here's an example by bricelam on 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();
}
好吧,正如在对问题的评论中已经注意到的那样,有一个 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 版本中解决。
目前,所有默认 Startup.cs
流程在每个与数据库相关的操作上执行,例如删除数据库、添加迁移、将数据库更新为迁移等
我在 Startup
中有大量特定于应用程序的代码,仅当应用程序 运行 真实时才需要调用这些代码。那么我如何从迁移或其他与数据库相关的 dotnet
命令中检测到 Startup
class 运行。
documentation is still a bit unclear as to why this occurs. I've yet to find any concrete answer as to why it runs Startup.Configure
. In 2.0 it's recommend to move any migration/seeding code to Program.Main
. Here's an example by bricelam on 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();
}
好吧,正如在对问题的评论中已经注意到的那样,有一个 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 版本中解决。