我有一个Entity Framework Core + ASP.NET Core应用程序,当我的应用程序启动时,我想确保创建数据库,并最终(一旦我有迁移)我想确保它们也运行。< / p>
最初我将Database.EnsureCreated()
放入DbContext
的构造函数中,但每次有人点击我的应用程序时都会运行,因为每次都会创建DbContext
的新实例。
我试着将它放入我的启动代码中,但是我需要一个DbContext
的实例才能做到这一点,目前还不清楚如何获得一个。我正在配置EF:
serviceCollection.AddEntityFramework()
.AddSqlServer()
.AddDbContext<Models.MyContext>(options => options.UseSqlServer(...));
我没有看到从服务集合中获取DbContext实例的方法,而且我没有看到任何适当的单例来注入DbContext,所以我可以进行一次性初始化。
那么确保每个应用程序运行时调用一次与我的DbContext相关的代码的最佳位置是什么?
答案 0 :(得分:5)
我想知道为什么你会跑去运行EnsureCreated作为你服务的一部分。您确实希望您的网络服务器创建或更新数据库架构吗?如果数据库不是最新的,为什么网络服务器会启动并提供请求?
您是否真的非常信任您的迁移,以至于它们在执行时不会破坏数据,您不希望在运行数据后对其进行测试?
此外,这将要求您为webserver数据库用户授予更改数据库架构的权限。这本身就是一个漏洞 - 接管您的网络服务器的人将能够修改您的数据库架构。
我建议您创建数据库并在您自己运行的小实用程序中应用迁移,而不是作为Web应用程序的一部分。
答案 1 :(得分:3)
在撰写本文时,没有一个正确的&#34;在应用程序启动时运行代码,以便它在请求范围内执行(请参阅https://github.com/aspnet/Hosting/issues/373)。
目前,解决方法是执行以下操作,但它不会在更复杂的多应用程序方案中工作(请参阅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();
}
}
}
答案 2 :(得分:0)