資料植入
資料植入是使用初始資料集來填入資料庫的程式。
EF Core 有數種方式可以達成此目的:
- 模型種子資料
- 手動移轉自訂
- 自訂初始化邏輯
模型種子資料
不同于 EF6,在 EF Core 中,植入資料可以與實體類型產生關聯,做為模型組態的一部分。 然後 EF Core 移轉 可以自動計算將資料庫升級至新版本模型時,需要套用哪些插入、更新或刪除作業。
注意
移轉只會在判斷應該執行的作業以將種子資料放入所需狀態時,才會考慮模型變更。 因此,對移轉外部執行的資料所做的任何變更可能會遺失或造成錯誤。
例如,這會在 中設定 Blog
的 OnModelCreating
種子資料:
modelBuilder.Entity<Blog>().HasData(new Blog { BlogId = 1, Url = "http://sample.com" });
若要新增具有關聯性的實體,必須指定外鍵值:
modelBuilder.Entity<Post>().HasData(
new Post { BlogId = 1, PostId = 1, Title = "First post", Content = "Test 1" });
如果實體類型具有陰影狀態的任何屬性,匿名類別就可以用來提供值:
modelBuilder.Entity<Post>().HasData(
new { BlogId = 1, PostId = 2, Title = "Second post", Content = "Test 2" });
擁有的實體類型可以以類似的方式植入:
modelBuilder.Entity<Post>().OwnsOne(p => p.AuthorName).HasData(
new { PostId = 1, First = "Andriy", Last = "Svyryd" },
new { PostId = 2, First = "Diego", Last = "Vega" });
如需更多內容, 請參閱完整的範例專案 。
將資料新增至模型之後, 應該使用移 轉來套用變更。
提示
如果您需要將移轉套用為自動化部署的一部分,您可以 建立可在執行前預覽的 SQL 腳本 。
或者,您可以使用 context.Database.EnsureCreated()
來建立包含種子資料的新資料庫,例如測試資料庫,或使用記憶體內部提供者或任何非關係資料庫時。 請注意,如果資料庫已經存在, EnsureCreated()
就不會更新資料庫中的架構或植入資料。 如果您打算使用移轉,就不應該呼叫 EnsureCreated()
關係資料庫。
模型種子資料的限制
這種類型的種子資料是由移轉所管理,而且腳本會更新資料庫中已存在的資料,而不需要連線到資料庫。 這會施加一些限制:
- 即使通常由資料庫產生主鍵值,也必須指定主鍵值。 其將用來偵測移轉之間的資料變更。
- 如果以任何方式變更主鍵,則會移除先前植入的資料。
因此,這項功能最適用于預期不會在移轉之外變更的靜態資料,且不相依于資料庫中的任何其他專案,例如郵遞區號。
如果您的案例包含下列任一項,建議您使用上一節所述的自訂初始化邏輯:
- 用於測試的暫存資料
- 相依于資料庫狀態的資料
- 大型資料(植入資料會在移轉快照集中擷取,而大型資料可以快速導致大量檔案和效能降低)。
- 需要資料庫產生索引鍵值的資料,包括使用替代索引鍵作為身分識別的實體
- 需要自訂轉換的資料(不是由 值轉換 處理),例如某些密碼雜湊
- 需要呼叫外部 API 的資料,例如 ASP.NET 核心身分識別角色和使用者建立
手動移轉自訂
將移轉新增至指定 HasData
之資料的變更會轉換成對 、 UpdateData()
和 DeleteData()
的 InsertData()
呼叫。 解決某些限制 HasData
的其中一種方法是手動將這些呼叫或 自訂作業 新增至移轉。
migrationBuilder.InsertData(
table: "Blogs",
columns: new[] { "Url" },
values: new object[] { "http://generated.com" });
自訂初始化邏輯
執行資料植入的簡單且強大方式,是在主要應用程式邏輯開始執行之前使用 DbContext.SaveChanges()
。
using (var context = new DataSeedingContext())
{
context.Database.EnsureCreated();
var testBlog = context.Blogs.FirstOrDefault(b => b.Url == "http://test.com");
if (testBlog == null)
{
context.Blogs.Add(new Blog { Url = "http://test.com" });
}
context.SaveChanges();
}
警告
植入程式碼不應該是一般應用程式執行的一部分,因為當多個實例執行時,這可能會導致並行問題,而且也需要應用程式具有修改資料庫架構的許可權。
根據部署的條件約束,初始化程式碼可以透過不同的方式執行:
- 在本機執行初始化應用程式
- 使用主要應用程式部署初始化應用程式、叫用初始化常式,以及停用或移除初始化應用程式。
這通常可以使用發行設定檔 來自動化 。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應