繁体   English   中英

我应该把Database.EnsureCreated放在哪里?

[英]Where should I put Database.EnsureCreated?

我有一个Entity Framework Core + ASP.NET Core应用程序,当我的应用程序启动时,我想确保创建数据库,并最终(一旦我有迁移)我想确保它们也运行。

最初我将Database.EnsureCreated()放入我的DbContext的构造函数中,但是每次有人点击我的应用程序时它都会运行,因为DbContext都会创建一个新的DbContext实例。

我试着把它放到我的启动代码中,但我需要一个我的DbContext实例才能做到这一点,目前还不清楚如何获得一个。 我正在配置EF如下:

serviceCollection.AddEntityFramework()
    .AddSqlServer()
    .AddDbContext<Models.MyContext>(options => options.UseSqlServer(...));

我没有看到从服务集合中获取DbContext实例的方法,我没有看到任何适当的单例来注入DbContext,所以我可以做一些一次性初始化。

那么确保一些与我的DbContext相关的代码在每个应用程序运行时被调用一次的最佳位置是什么?

在撰写本文时,没有一个“正确”的地方在应用程序启动时运行代码,使其在请求范围内执行(请参阅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();
        }
    }
}

我想知道为什么你会跑去运行EnsureCreated作为你服务的一部分。 真的希望您的Web服务器创建或更新数据库架构吗? 如果数据库不是最新的,为什么网络服务器会启动并提供服务?

您是否真的非常信任您的迁移,以至于它们在执行时不会破坏数据,您不想在运行后测试数据?

此外,这将要求您为webserver数据库用户授予更改数据库架构的权限。 这本身就是一个漏洞 - 接管您的网络服务器的人将能够修改您的数据库架构。

我建议您创建数据库并在您自己运行的小实用程序中应用迁移,而不是作为Web应用程序的一部分。

我认为zmbq的建议是正确的,并且有一种方法可以确保迁移与部署一起运行,以便使用Visual Studio的发布功能使二进制文件和数据库更改保持同步。

针对IIS实例发布时,可以指定要用于运行所需迁移的目标数据库连接字符串:

发布时使用的实体框架迁移

这将确保仅在需要时(不是每次应用程序启动时)应用更改,并且应用程序使用最少的数据库权限(即数据库编写器,读取器等)运行,而不是更改表,创建索引等的权限。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM