

EF Core 測試小技巧 - 快速建立資料表
source link: https://blog.darkthread.net/blog/ef-core-ensurecreated/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

EF Core 測試小技巧 - 快速建立資料表
2022-04-11 09:41 AM 1 523截至目前,我的 EF Core 範例都是用 dotnet ef migrations create 產生建立(或升級) Schema 所需程式,再透過 dotnet ef database update 或 DbContext.Database.Migrate() 套用 Migration 建立或修改資料表。
但在雛型驗證階段或跑自動測試,有個更省事的做法 - DbContext.Database.EnsureCreated(),其執行規則為:
- 若資料庫存在且有任何資料表,不執行動作,傳回 false
- 若資料庫存在且沒有任何資料表,則使用 EF Model 建立資料表
- 若資料庫不存在,則先建立資料庫再依 EF Model 建立資料表
EnsureCreated() 的缺點是適用空白資料庫全新建立,不像 Migration 可依資料庫現況增減資料表、欄位、索引,再套用現存資料庫將 Schema 更新到最新狀態。用 EnsureCreated() 建立的資料表,之後也無法再用 Migration 套用更新。
實驗驗證或自動測試時,資料庫通常測完即抛,沒有後續更新問題,便適合使用 EnsureCreated(),省去建立 Migration 程序。
以昨天的 StaticFileDbContext 為實例,我想對它做自動測試,試試資料表寫入是否正常,可以這樣做:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using Microsoft.EntityFrameworkCore;
using Microsoft.Data.Sqlite;
using Drk.AspNetCore.FileProviders;
using System.Linq;
using System.Text;
namespace test_dbctx;
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var dbPath = "test.sqlite";
// 清除之前殘留資料庫檔案
if (File.Exists(dbPath)) File.Delete(dbPath);
var opt = new DbContextOptionsBuilder<StaticFileDbContext>()
.UseSqlite($"data source={dbPath}").Options;
var ctx= new StaticFileDbContext(opt);
// 建立資料表
ctx.Database.EnsureCreated();
var resp = new StaticFileDbRepository(ctx);
Assert.AreEqual(ctx.StaticFileIndices.Count(), 0);
var userId = "jeffrey";
var clientIp = "::1";
resp.UpdateFile("/test.txt", Encoding.UTF8.GetBytes("ABC"), userId, clientIp);
Assert.AreEqual(ctx.StaticFileIndices.Count(), 2);
var testTxt = Encoding.UTF8.GetString(resp.ReadFile("/test.txt").Content);
Assert.AreEqual(testTxt, "ABC");
}
}
使用 .NET CLI 一鏡到底之測試程序如下:
dotnet new mstest -o test-dbctx
cd test-dbctx
dotnet add package Drk.AspNetCore.FileProviders
rem 將 UnitTest1.cs 換成上面的程式碼
dotnet test
測試成功!
不過,由於 EnsureCreated() 的偵測條件是資料庫不存在任何資料表,若有多個 DbContext 共用資料庫,只有第一個執行 EnsureCreated() 的 DbContext 會建立資料表,第二個 DbContext EnsureCreated() 時會因已存在第一個 DbContext 的資料表而不執行動作(如下圖),此時需依賴 Migration 才能完整建立。單元測試多半聚焦單一 DbContext,倒是可安心使用。
Recommend
-
9
-
14
添加串聯與減震功能,ADATA XPG VENTO PRO 120 PWM 風扇測試老牌溫柔颱風信用好,VENTO PRO 120 PWM 添加實用機能更迎合時代需求。電競產品已成為電腦零組件與週邊產品一股不可忽略的勢力,國內廠商 ADATA 威剛科技也透過旗下 XPG...
-
9
Azure SQL Database 的 Elastic p...
-
4
快速產生 SQLite 資料的方式:一分鐘內產生十億筆資料 在「Towards Inserting One Billion Rows in SQLite Under A Minute」這邊看到作者想要在一分鐘內在 MBP 2019 上面寫 1B 筆...
-
7
架設一個測試網站,最常見的需求就是一個網站(Azure Web App)外加一個資料庫(Azure SQL Database),如果有檔案儲存需求,頂多就再加一個儲存體帳戶(Azure Storage Account)就可以搞定。這篇文章我將分享如...
-
6
In-Memory Provider 與 SQLite In-Memory Mode-黑暗執行緒 撰寫 EF Core 相關測試時,若偏向單元測試性質,除了真的連接資料庫實測試,若測試內容未高度依賴資料庫特性,還有更輕便、易控制且有效率的選擇。 使用真實資料庫是最省事最逼真的做法,但實務...
-
3
Postgres 在建立索引時,會阻塞 DML 也就是 lock 整個 table 的寫入(讀取則不影響),所以當需要對大資料量的 Table 打 index 時,會造成有 Downtime 時間,這在 Production 這種高並發的環境下是不適合的。並發計算建立 indexPostgres 在建立...
-
4
EF Core 新增或更新資料 (UPSERT) 的簡便寫法-黑暗執行緒 資料庫程式有一種常見的應用情境:傳入一筆資料,以 Primary Key 比對,若該筆資料不存在就新增,若已存在則改更新欄位。 這種動作被稱為 INSERT OR UPDATE,或簡稱
-
4
EF Core 多 DbContext 共用資料庫 EnsureCreated 失效問題-黑暗執行緒 讓 EF Core 依據 Entity 類別定義自動在資料庫新增資料表,主要有兩種做法:使用 Migrati...
-
8
ASP.NET Core Minimal API 整合測試-黑暗執行緒 這篇聊聊 ASP.NET Core 的整合測試。 假設我寫了一個沒啥營養的展示用 Minimal API,其中宣告 GuidServi...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK