使用 EF Core 1.0 實作 Seeding、自定義慣例與攔截器


這篇貼文是 .NET 團隊中的軟體工程師 Alina Popa 撰寫的。
 

簡介

Entity Framework CoreEF Core)是一個輕量且可延伸的 Entity FrameworkEF)版本,它跨平台而且支援多個資料庫供應商。您可以在 Entity Framework 中找到 EF Core EF6 的比較。

當您把一個應用程式從 EF6 移到 EF Core,會遇到一些原來存在於 EF6 的功能,卻沒有出現或還沒有在 EF Core 實作。不過,還是有辦法在 EF Core 中實作出同等的功能。

 

Seeding

在 EF6 時,可以透過覆寫底下其中一個 Seed() 方法來初始資料庫中的資料:

EF Core 沒有提供相似的 API,因為資料庫初始設定已經不在 EF Core 中了。想要初始資料庫,則應該把資料庫初始化程式碼放到應用程式的 startup。如果您在使用移轉(migration),呼叫 context.Database.Migrate(),否則使用 context.Database.EnsureCreated()/EnsureDeleted()

初始化資料庫的模式在 Entity Framework Core GitHub repo 中的 issue 3070 討論。建議的實作方式是在 Startup.Configure() 當中的 Service Scope 執行資料庫初始化程式碼:

您可以在找到一個使用移轉的資料庫初始化例子。MusicStore 範例也是使用這種植入的模式。

請注意,一般而言建議手動採用這些操作(而不要在 startup 自動執行移轉與初始化),避免多個伺服器的競態條件,與無意的更動。

 

自定義慣例

Entity Framework 6 我們可以透過使用 model-based 的慣例,建立自定義的屬性與表格配置。例如,以下的程式碼在 EF6 建立一個慣例,當欄位名稱超過 30 個字元,會擲回例外狀況。

EF Core 沒有提供 IStoreModelConvention 介面,然而我們可以透過訪問內部服務來建立慣例(在 EF Core 延伸較低層的元件)。在以下的例子,我們實作了一個 model 的驗證程式,檢查太長的表格或欄位名稱:

請注意這個 model 不是唯讀的,它可以在迴圈內更改。

 

攔截器

Entity Framework 6 使用 IDbCommandInterceptor,提供了攔截內容的能力。攔截器就在指令或查詢送到資料庫前與送到後,讓您進入管道。 Entity Framework Core 目前還沒有任何攔截器,但是可以透過匯入攔截器相關的功能子集來達到,例如 DbContext.SaveChanges

關於上面這個範例:

  • 呼叫 ChangeTracker.DetectChanges() 是為了確保變更追蹤器有在注意實體的改動,例如:如果您設定 .Category 到一個在現存 Product 上新的 Category,新的 Category 將不會被追蹤直到 DetectChanges() 被呼叫或它明確地透過 DbSet 或 ChangeTracker 新增。
  • 在呼叫 base.SaveChanges 之前,將 AutoDetectChangesEnabled 設定為 false 是因為效能的原因,為了避免再呼叫 DetectChanges()。

攔截器與 seeding 在功能待辦項目中的優先度是很高的,而 Entity Framework 團隊計畫會在近期處理它們。

 

實用連結

 

本文翻譯自 Implementing Seeding, Custom Conventions and Interceptors in EF Core 1.0


若對以上技術及產品有任何問題,很樂意為您服務! 請洽:台灣微軟開發工具服務窗口 – MSDNTW@microsoft.com / 02-3725-3888 #4922

Comments (0)

Skip to main content