關於 Migrations 本篇將討論以下幾個問題
1. Migrations 基本操作
2. Migrations 應用
測試環境:
OS:Windows 10
IDE:Visual Studio 2019
MS SQL:SQL Server 2019 Linux
SSMS:Microsoft SQL Server Management Studio 18
1. Migrations 基本操作
以下提供 .NET Core CLI & PowerShell 兩種操作方式,可依據個人習慣使用。
1.1 初次建立 Migrations
EF Core 會在專案中建立名為 Migrations 的目錄,並產生一些相關檔案。
操作方式 | 語法 |
---|---|
.NET Core CLI | dotnet ef migrations add InitialCreate |
PowerShell | Add-Migration InitialCreate |
若不想建立在跟目錄,也可透過 -OutputDir 指定目錄位置。
操作方式 | 語法 |
---|---|
.NET Core CLI | dotnet ef migrations add InitialCreate --output-dir [指定目錄] |
PowerShell | Add-Migration InitialCreate -OutputDir [指定目錄] |
1.2 新增 Migrations
依據 Context 中註冊的 Model 的變更,與舊有 Migrations 比較產生差異紀錄,每次新增的 Migrations 中包含兩個部分,除了自動產生的部分外也可以自定義所需屬性
- Up:更新時的操作
Down:還原時的操作
public partial class AddFirstNameAndLastName : Migration { // 更新時的操作 protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.AddColumn<string>( name: "FirstName", table: "Users", type: "nvarchar(max)", nullable: true); migrationBuilder.AddColumn<string>( name: "LastName", table: "Users", type: "nvarchar(max)", nullable: true); } // 還原時的操作 protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropColumn( name: "FirstName", table: "Users"); migrationBuilder.DropColumn( name: "LastName", table: "Users"); } }
操作方式 | 語法 |
---|---|
.NET Core CLI | dotnet ef migrations add [MigrationName] |
PowerShell | Add-Migration [MigrationName] |
※ [MigrationName] 命名建議依據團隊規範來建立,以便後續管理。
1.3 移除 Migrations
移除前一次 Migration,還未更新至資料庫的話,可以直接刪除 Migrations 目錄中的檔案或是透過語法來刪除。
操作方式 | 語法 |
---|---|
.NET Core CLI | dotnet ef migrations remove |
PowerShell | Remove-Migration |
1.4 查詢 Migrations
列出全部 Migrations
操作方式 | 語法 |
---|---|
.NET Core CLI | dotnet ef migrations list |
PowerShell | Get-Migration |
1.5 套用至資料庫
以上操作都只是在專案中進行,最後還需要透過 Update 語法與資料庫同步,一般會直接更新至最新版本
操作方式 | 語法 |
---|---|
.NET Core CLI | dotnet ef database update |
PowerShell | Update-Database |
1.6 將已存在 Migrations 套用至空白資料庫
操作方式 | 語法 |
---|---|
.NET Core CLI | dotnet ef migrations script |
PowerShell | Script-Migration |
2. Migrations 應用
2.1 情境一:使用 SQL 語法
透過 migrationBuilder.Sql
除了範例中簡單的將 FirstName 與 LastName 組合起來之外,還可以透過以下五種複雜操作來處理資料
- Stored procedures 預存程序
- Full-Text Search 全文檢索搜尋
- Functions 函式
- Triggers 觸發程序
- Views 檢視
public partial class AddFirstNameAndLastName : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "FirstName",
table: "Users",
type: "nvarchar(max)",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "LastName",
table: "Users",
type: "nvarchar(max)",
nullable: true);
migrationBuilder.Sql(
@"
UPDATE Users
SET Name = FirstName + ' ' + LastName;
");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "FirstName",
table: "Users");
migrationBuilder.DropColumn(
name: "LastName",
table: "Users");
}
}
2.2 情境二:欄位刪除的順序
假設原本使用 FirstName
& LastName
兩個欄位,而之後想改用 Name
一個欄位來取代。
先刪除欄位再新增欄位,會將舊資料全部刪除,Name
中的資料需要重新建立
migrationBuilder.DropColumn(
name: "FirstName",
table: "Users");
migrationBuilder.DropColumn(
name: "LastName",
table: "Users");
migrationBuilder.AddColumn<string>(
name: "Name",
table: "Users",
nullable: true);
可以透過 migrationBuilder.Sql
將 FirstName
& LastName
兩個欄位合併後填入 Name
中再刪除
// 透過 SQL 合併兩個欄位資料,處理完後刪除舊欄位
migrationBuilder.AddColumn<string>(
name: "Name",
table: "Customer",
nullable: true);
migrationBuilder.Sql(@"
UPDATE Users
SET Name = FirstName + ' ' + LastName;
");
migrationBuilder.DropColumn(
name: "FirstName",
table: "Users");
migrationBuilder.DropColumn(
name: "LastName",
table: "Users");
完整程式碼
GitHub:CodeFirst