---------- 20190205 ref: https://stackoverflow.com/questions/13627829/about-dbset-and-dbcontext Intuitively, a DbContext corresponds to your database (or a collection of tables and views in your database) whereas a DbSet corresponds to a table or view in your database. So it makes perfect sense that you will get a combination of both! You will be using a DbContext object to get access to your tables and views (which will be represented by DbSet's) and you will be using your DbSet's to get access, create, update, delete and modify your table data. If you have 10 tables in your database and your application works with 5 of them (let us call them Table1 - Table 5) it would make sense to access it using a MyAppContext object where the MyAppContext class is defined thus: public class MyAppContext : DbContext { public MyAppContext () : ; public DbSet Table1 { get; set; } public DbSet Table2 { get; set; } public DbSet Table3 { get; set; } public DbSet Table4 { get; set; } public DbSet Table5 { get; set; } } Note that, for instance, the identifier Table1 is used both as the name of a type and as a name of a property in the defined context type. What you see above is quite typical. An example of a class that corresponds to a table schema is given below: public class Table1 { public int Id {get; set;} public string AStringField {get; set;} //etc. } Have a look here for more information: http://entityframeworktutorial.net/ ---------- 20190205 ref: https://jeffprogrammer.wordpress.com/2017/01/19/entity-framework-code-first/ 前言 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(new CreateDatabaseIfNotExists()); } public DbSet Students { get; set; } } 三、Web.config 設定資料連線 我們使用預設的 LocalDB 四、於 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。