前言
Entity framework 提供一個以程式為基礎來建立資料庫的方式,稱為 Code First。以下簡易示範作法。
一、建立資料表模型(Model)
public class Student { public int ID { get; set; } public string Name { get; set; } }
.
二、建立繼承 DbContext 的類別
using System.Data.Entity; public class EFDBContext:DbContext { public EFDBContext():base("DefaultConnection") { Database.SetInitializer<EFDBContext>(new CreateDatabaseIfNotExists<EFDBContext>()); } public DbSet<Student> Students { get; set; } }
.
三、Web.config 設定資料連線
我們使用預設的 LocalDB
<connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-CodefirstSample-20170118110538.mdf;Initial Catalog=aspnet-CodefirstSample-20170118110538;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>
.
四、於 VS Package Manager Console 輸入指令
開啟 Package Manager Console
輸入指令:
(一) Enable-Migrations -ContextTypeName 專案名稱.Models.繼承 DbContext 的類別名稱
例如,我們的專案名稱是:CodefirstSample。繼承 DbContext 的類別名稱是:EFDBContext。如下所示:
PM> Enable-Migrations -ContextTypeName CodefirstSample.Models.EFDBContext
執行指令之後會在專案裡建立一個「Migrations」目錄以及「Configuration.cs」檔案
(二) add-migration 移轉名稱
這指令會在專案的「Migrations」目錄內建立一個結構檔,VS 依據這個檔案來異動資料庫。
PM> add-migration v1
指令執行後,主控台會出現以下訊息
正在為移轉 'v1' 建立結構。 這個移轉檔案的設計工具程式碼包括目前 Code First 模型的快照。這個快照是用於為下一個移轉建立結構時計算模型的變更。如果您對模型進行其他變更,而且想將變更包含在這個移轉中,只要再次執行 'Add-Migration v1' 就能重新建立結構。
下一次資料庫的異動會檢查比對這個檔案來做資料庫異動。
(三) update-database
PM> update-database
指令執行後,主控台會出現以下訊息
正在套用明確移轉: [201701181514254_v1]。 正在套用明確移轉: 201701181514254_v1。 正在執行 Seed 方法。
指令執行成功後,會建立資料庫並且建立一個 __MigrationHistory 資料表,紀錄每一次的異動,提供下一次異動的比對。
四、資料庫資料表的異動
假設我們在 Student 這個模型加上一個欄位:Add。編譯程式,執行指令 add-migraion v2。
模型加上一個欄位:Add。
public class Student { public int ID { get; set; } public string Name { get; set; } public string Add { get; set; } }
執行指令 add-migraion v2
public partial class v2 : DbMigration { public override void Up() { AddColumn("dbo.Students", "Add", c => c.String()); } public override void Down() { DropColumn("dbo.Students", "Add"); } }
最後執行指令更新資料庫:update-database
在資料庫的 __MigrationHistory 資料表可以看到二次異動紀錄。
測試
再於 Student 模型加入一個欄位 class
public class Student { public int ID { get; set; } public string Name { get; set; } public string Add { get; set; } public string Class { get; set; } }
然後於資料庫移除 __MigrationHistory 資料表中的第二次異動紀錄。也就是只剩下一個異動紀錄,紀錄的是創建資料表。
這時執行指令 add-migration v3 ,觀察產生的結構檔如下:
public partial class v3 : DbMigration { public override void Up() { AddColumn("dbo.Students", "Add", c => c.String()); AddColumn("dbo.Students", "Class", c => c.String()); } public override void Down() { DropColumn("dbo.Students", "Class"); DropColumn("dbo.Students", "Add"); } }
原本的第二次異動紀錄會被產生。這意味著,每次執行指令 add-migration,VS會撈取 __MigrationHistory 資料表,取出最後一次異動的資料,和程式的模型比較,依據二者差異產生結構檔。
Up / Down method
Up 這個方法是讓 EF 執行目前你要更新資料庫的內容。 Down 方法則是當你想恢復某個版本, EF 會執行該版本之後的 Down 方法,來恢復。
http://stackoverflow.com/questions/24560469/asp-net-database-migration-whats-the-down-method-for
問題
多人開發下,經常發生一個狀況:某甲異動了資料庫,但某乙的程式的資料模型尚未更正。這時某乙編譯自己的程式後,讀取資料庫時會報錯,指出程式的資料模型與資料庫不一致。
這意味著,Entity framework 在存取資料庫之前會先檢查程式與資料庫的資料模型是否一致。問題是,Entity framework 如何快速檢查?
它會檢查程式的資料模型與資料庫的 Migration history table。如果你刪除掉 history table 某筆紀錄,專案內 Migration 資料夾對應的結構檔也移除,即使資料庫與程式的資料模型一致,當讀取資料庫也會報錯。@_@
必須再執行一次 Migration 解決這問題。但在 Up()內的重複產生的語法都要清除。
如果不想要檢查程式資料模型與資料庫是否一致,請刪除資料庫的 Migration history table。
感想
在現實開發世界,Code first 的存在很方便,而 database first 的存在也是必要。為了整合不同資料來源的資料,兩者經常同時使用在同一專案。
不同於 database first, code first 以程式設計師的專案為主,當多人共同開發時,要特別謹慎,溝通必須清楚。
個人來說,我比較偏好 database first。