簡體   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