前言
設計資料表時,有個問題其實比想像中關鍵:這張表的主鍵(PK),到底是誰負責生出來的?
最直覺的答案是「資料庫啊」——int IDENTITY 自動加一,或 SQL Server 的 NEWSEQUENTIALID(),
反正 INSERT 下去資料庫就會幫我填好。寫起來省事,大家一開始也都這樣用。
但用久了會踩到一些尷尬的狀況:
- 我想在存檔之前就知道這筆資料的 Id(要先建關聯、要回傳給前端、要寫 log),但值在資料庫那邊,
非得SaveChanges()之後才拿得到。 - 寫單元測試想驗證物件之間的關聯,結果沒有真資料庫就生不出 Id。
- 一張主檔搭多張明細,明細要塞外鍵,但主檔 Id 還沒生出來,整個串接卡住。
於是另一條路浮上來:讓應用程式自己產生主鍵。我們團隊的開發規範也是這樣訂的——
所有實體的主鍵一律標上 [DatabaseGenerated(DatabaseGeneratedOption.None)],
把產生主鍵的責任從資料庫手上收回來。
這篇就把「資料庫產生 PK」與「應用程式自訂 PK」兩條路講清楚,
並用 EF Core 內建的 SequentialGuidValueGenerator 示範兩種落地寫法。
2026/6/28大約 12 分鐘