---
# System prepended metadata

title: C# Migration 管理資料庫結構變更
tags: [C#]

---

# C# Migration 管理資料庫結構變更
Migration (遷移) 用於 管理資料庫結構變更，例如：
* 新增/刪除資料表
* 變更欄位類型
* 新增索引或外鍵關係

內大多為Database連結問題，還有兩個專案資料相連的操作

[TOC]
## 🔹 如何使用 Migration？
使用 EF Core 的 dotnet ef 指令來操作 Migration。
NuGet套件管理員(N)>>套件管理器主控制台(O)>>輸入至另
![image](https://hackmd.io/_uploads/H1gEwGBh1g.png=50%)

### 安裝 Entity Framework Core CLI
如果專案還沒安裝 EF Core CLI，請先安裝：

```bash=
dotnet tool install --global dotnet-ef
```
### 新增 Migration
當你在 DbContext 內 新增 或 修改 DbSet< T >，就要執行：

```bash=
dotnet ef migrations add InitDatabase
```
✅ 建立 Migrations 資料夾
✅ 產生 InitDatabase 遷移檔 (.cs)
    
### 更新資料庫
將 Migration 變更應用到資料庫：

```bash=
dotnet ef database update
```
✅ 根據 Migration 自動修改資料庫結構
✅ 在資料庫中建立 __EFMigrationsHistory 記錄遷移歷史

### 刪除 Migration
```bash=
Remove-Migration(這應該是名稱)
```
如果你新增了錯誤的 Migration，可以移除：

```bash=
dotnet ef migrations remove
```
### 清空資料庫 然後重新建立：
```bash=
Drop-Database
Update-Database
```
## 🔹 Migration 實際案例
假設有一個 User 類別：

```csharp=
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}
```
### 新增 Migration
修改 User 類別，例如新增 Email 欄位：

```csharp
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; } // 新增欄位
}
```
然後執行：

```bash=
dotnet ef migrations add AddUserEmail
dotnet ef database update
```
這樣，資料庫的 User 表格會自動新增 Email 欄位。
![image](https://hackmd.io/_uploads/SJ12lKtnJg.png=50%)
## Up() 和 Down() 
就會出現Up() 和 Down() 
📌 例如：
假設我們有一個原本的 Table：
```csharp=
public class Table
{
    [Key]
    public string CheIn { get; set; }
    public string CheOut { get; set; }
    public string People { get; set; }
    public string Room { get; set; }
}
```
如果你在 Table 類別中 新增 一個 Pay 欄位：
```csharp=
public class Table
{
    [Key]
    public string CheIn { get; set; }
    public string CheOut { get; set; }
    public string People { get; set; }
    public string Room { get; set; }
    public string Pay { get; set; }  // 新增的欄位
}
```
然後執行：
```bash=
Add-Migration AddPayColumn
```
EF 會自動產生以下的 Migration：
```csharp=
public partial class AddPayColumn : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.Tables", "Pay", c => c.String());
    }

    public override void Down()
    {
        DropColumn("dbo.Tables", "Pay");
    }
}
```
### Up() 和 Down() 的作用
* Up()：用來套用這次的變更，例如新增表格、修改欄位、建立索引等。
* Down()：用來還原這次的變更，讓你可以 Update-Database -TargetMigration PreviousMigration 來回到前一個版本。
    
## 總結
| 指令                             | 用途                        |
|----------------------------------|-----------------------------|
| dotnet ef migrations add <名稱>  | 建立遷移 (記錄資料庫變更)  |
| dotnet ef database update         | 套用遷移 (更新資料庫)      |
| dotnet ef migrations remove       | 移除最新遷移                |
| dotnet ef database drop           | 刪除整個資料庫 (⚠小心使用) |

透過 Migration，開發者可以安全、快速地修改資料庫結構，避免手動寫 SQL 來管理變更！
    
## 💡Database連結
[C#Database1Entities and DataTable](/_5KJ4EsHTtW5GGr8haVaGQ)這裡有詳細寫到
```bash=
Enable-Migrations

Add-Migration InitialCreate //(name)

Update-Database
```
## 是否需要連網使用?
Migration 本身**不需要聯網**，但如果你的 資料庫 (DB) 在遠端伺服器，那麼 執行 Migration 時就需要網路 來連接資料庫。

### Migration 需要聯網的情況
1. 你的資料庫在遠端伺服器 (例如：Azure SQL、AWS RDS、MySQL Server)
執行 Update-Database 時，會連接到遠端資料庫，因此需要網路。
2. 使用 Entity Framework Core 並且 DbContext 指向遠端資料庫
dotnet ef migrations add 本身不需要網路
但 dotnet ef database update 會執行 SQL 指令，若資料庫在雲端，則需要網路。
----
### Migration 不需要聯網的情況
1. 本機 (Local) 資料庫
如果你用 SQL Server LocalDB、SQLite、或內建 SQL Server，Migration 可以完全離線執行。
2. 只建立 Migration，不更新資料庫
Add-Migration 只是產生變更檔案 (.cs)，這步驟不需要連接資料庫。
---
### 總結
✅ 建立 Migration (Add-Migration) → 不需要網路
✅ 執行 Migration (Update-Database) → 需要網路 (如果資料庫在遠端)
❌ 如果資料庫在本機 → 完全不需要網路
## Migration命名相同會連到其他資料表嗎？
**不會❌**直接影響
但如果你在不同的專案或資料庫中 使用相同的 Migration 名稱，它們仍然是獨立的，不會自動連結。

Entity Framework Core 會根據 Migrations 資料夾內的內容，以及 __MigrationHistory 表（或 EFMigrationsHistory 表）來決定哪些遷移已經應用到資料庫。

但是 如果你在同一個資料庫上執行 Update-Database，EF 會按照 MigrationHistory 來決定是否需要應用新的變更。
## 同一個資料庫(Database)或資料表(Table)名稱相同，連結Migration會相通資料嗎?
**是的✔️**
如果不同專案的 DbContext 連接到同一個資料庫，並且資料表名稱相同，它們會共享相同的資料表。這可能會導致一些問題，例如：

### 可能遇到的問題
1. Migration 衝突
如果兩個專案各自有 Migrations，執行 Update-Database 可能會產生衝突，因為 EF 會嘗試同步 DbContext 定義，但可能不一致。
2. 資料不一致
如果兩個專案的 Table 類別（Entity Model）欄位不同，但指向同一張資料表，可能會造成某些欄位找不到或型別不匹配的錯誤。
3. 不同 DbContext 互相影響
若專案 A 和專案 B 都連接 DatabaseName=MyDB;，當專案 A 變更 Schema 並執行 Update-Database，專案 B 可能會遇到不相容的結構。

---
### 如何避免問題？
✅ 方法 1：確保不同專案的 DbContext 一致

若兩個專案要共用同一個資料庫，請確保 DbContext 內的 DbSet 定義完全一致：
```csharp=
public class Database : DbContext
{
    public DbSet<Table> Tables { get; set; }
}
```
✅ 方法 2：共用相同的 Migrations
選擇一個專案來負責 Migrations，其他專案不要執行 Enable-Migrations，而是共享相同的 Migrations 目錄。
✅ 方法 3：使用不同的 MigrationsHistoryTable
你可以為不同專案設定不同的 Migrations 記錄表，這樣它們不會互相干擾：
```csharp=
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema("ProjectA"); // 為不同專案指定不同 Schema
}
```
✅ 方法 4：使用不同的資料庫名稱

如果不同專案只是測試用途，建議它們使用不同的資料庫名稱，例如：
```bash=
DatabaseName=MyDB_Dev;
DatabaseName=MyDB_Prod;
```
### 結論
如果不同專案指向相同的資料庫且表名相同，它們確實會共用相同的資料表。
為了避免衝突，建議使用共用 Migrations、確保 DbContext 一致或使用不同的資料庫名稱。🚀
## 如果資料變得混亂(刪除~
可以：
```bash=
Remove-Migration
Add-Migration NewMigration
Update-Database
```
或手動刪除那個資料夾
並重新建立：
```bash=
Enable-Migrations

Add-Migration NewMigration

Update-Database
```




