EF Core 是 ASP.NET Core 官方推薦的資料庫存取方式。雖然在 ASP.NET Core 裡,你還是可以沿用古法,自己開 SqlConnection,自己寫 T-SQL 透過 SqlCommand、SqlParameter 讀寫資料庫,沒什麼不行。但以下 Visual Studio 2019 + EF Core 的整合示範,或許可以讓大家改觀。

EF Core 有個神奇功能是資料表不存在時會自動建立,版本太舊還會自動調整 Schema 更新,這功能的專業術語叫 Migration。(延伸閱讀:EF Core 筆記 1 - 概論)

在前一篇文章中,我們已定義好 DailyRecord 型別打算存到 SQL 資料庫,若依傳統資料庫程式開發,下一步該是撰寫 CREATE TABLE 指令,開 SSMS 登入資料庫建好資料表才能繼續下一步。但 Entity Framework Code First 標榜開發者專心寫程式,不需操煩太多資料庫細節,甚至不用管資料要存 SQL、Oracle、MySQL 還是 SQLite,改一行程式就能換掉資料庫。(延伸閱讀:EF Core 筆記 4 - 跨資料庫能力展示)

以下會實際示範如何在用 EF Core Migration 在前一篇建好的 LocalDB Journal.mdf 生出 DailyRecord 資料表。

做法有兩種,之前我對命令列工具( dotnet ef )操作介紹較多,這回改用跟 Visual Studio 整合性較高的 PowerShell Console 示範。(延伸閱讀:Entity Framework Core 工具參考-Visual Studio 中的套件管理員主控台)

產生 Migration 程式

首先,先按 F6 建置一次專案。開啟 Tools / NuGet Package Manager / Package Manager Console:

在 Console 輸入指令 Install-Package Microsoft.EntityFrameworkCore.Tools 安裝 EF Core 工具,再輸入 Add-Migration InitialCreate 產生相關程式。

若執行成功,專案將會多一個 Migrations 資料夾,內含 yyyyMMddHHmmss_InitialCreate.cs 與 JournalDbContextModelSnapshot.cs 兩個類別檔:

加入自動建立或升級資料表程序

下一步是告訴 ASP.NET Core 在每次啟動前檢查資料表版本,不存在就現場新增,版本太舊就當場升級。最簡便的做法是修改 Startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
                //透過建構式參數取得 DBContext (依賴注入架構的標準做法)
                JournalDbContext dbContext)
{
    //檢查資料表是否已經存在,若不存在自動建立;若資料表存在但版本太舊符則自動更新。
    //在正式環境自動更新Schema有點可怕,我加了限定LocalDB執行的安全鎖
    if (dbContext.Database.GetDbConnection().ConnectionString.Contains("MSSQLLocalDB"))
    {
        dbContext.Database.Migrate();
    }
    //...以下省略...
}

透過建構式參數取得 JournalDbContext 是 ASP.NET Core DI 架構的標準做法 (延伸閱讀:筆記 - 不可不知的 ASP.NET Core 依賴注入ASP.NET Core 練習 - 依賴注入 DI),我們讓 Startup.Configuration() 在每次啟動 ASP.NET Core 網站時執行,DbContext.Database.Migrate()實現「若資料表不存在就新增,版本太舊就更新」,自動修改 Schema 在開發環境或測試環境還 OK,正式資料庫異動 Schema 耗時較久,多需事前規劃並通告相關單位,並安排備分、退版計劃,以工程方式進行,不太可能直接來。為此,我在程式加了一層保護鎖,比對連線字串確認是 SQL LocalDB 才執行。關於如何在正式環境套用 Migration 升級,可參考EF Core 筆記 5 - 淺談正式環境資料庫建立與換版

註:如果只想在沒有資料表時自動建立,還有另一個選擇是將將 dbContext.Database.Migrate() 改為 dbContext.Database.EnsureCreated()。使用 EnsureCreated() 的話不需要「產生 Migration 程式」步驟,但是未來資料庫 Schema 改版得手動處理,無法享受 Migration 機制的便利。

一切就緒後,按下 F5 執行程式,瀏覽器出現預設首頁,沒什麼特別。

但是回到 Visual Studio Server Explorer 檢查 Journal.mdf,可發現 Records 資料表已經建立完成,欄位依 DailyRecord 屬性而設,連索引都建好了:

就醬,我們連 SSMS 都沒開,就把網站需要的 Records 資料表準備好了。下一篇來體驗如何在五分鐘內靠 ASP.NET Core 的鷹架模版(Scaffolding)生出基本的清單 + 新增/修改/刪除/顯示網頁。

Demostration of using EF Core migrations to create table in database automatically.


Comments

# by

黑大,問個蠢問題, 程式怎麼知道Date欄位是unique?在那裏設定的?

# by

我看到在那裏設定了~

# by

我看到在那裏設定了~

Post a comment