# C# Migration 管理資料庫結構變更 Migration (遷移) 用於 管理資料庫結構變更,例如: * 新增/刪除資料表 * 變更欄位類型 * 新增索引或外鍵關係 內大多為Database連結問題,還有兩個專案資料相連的操作 [TOC] ## 🔹 如何使用 Migration? 使用 EF Core 的 dotnet ef 指令來操作 Migration。 NuGet套件管理員(N)>>套件管理器主控制台(O)>>輸入至另  ### 安裝 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 欄位。  ## 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 ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up