- 實體框架教程
- 實體框架 - 首頁
- 實體框架 - 概述
- 實體框架 - 架構
- 實體框架 - 環境設定
- 實體框架 - 資料庫設定
- 實體框架 - 資料模型
- 實體框架 - DbContext
- 實體框架 - 型別
- 實體框架 - 關係
- 實體框架 - 生命週期
- 實體框架 - 程式碼優先方法
- 實體框架 - 模型優先方法
- 實體框架 - 資料庫優先方法
- 實體框架 - 開發方法
- 實體框架 - 資料庫操作
- 實體框架 - 併發
- 實體框架 - 事務
- 實體框架 - 檢視
- 實體框架 - 索引
- 實體框架 - 儲存過程
- 實體框架 - 離線實體
- 實體框架 - 表值函式
- 實體框架 - 原生 SQL
- 實體框架 - 列舉支援
- 實體框架 - 非同步查詢
- 實體框架 - 持久化
- 實體框架 - 投影查詢
- 實體框架 - 命令日誌
- 實體框架 - 命令攔截
- 實體框架 - 空間資料型別
- 實體框架 - 繼承
- 實體框架 - 遷移
- 實體框架 - 渴望載入
- 實體框架 - 延遲載入
- 實體框架 - 顯式載入
- 實體框架 - 驗證
- 實體框架 - 跟蹤更改
- 實體框架 - 彩色實體
- 實體框架 - 程式碼優先方法
- 實體框架 - 第一個示例
- 實體框架 - 資料註釋
- 實體框架 - Fluent API
- 實體框架 - 初始化資料庫
- 實體框架 - 程式碼優先遷移
- 實體框架 - 多個 DbContext
- 實體框架 - 巢狀實體型別
- 實體框架資源
- 實體框架 - 快速指南
- 實體框架 - 有用資源
- 實體框架 - 討論
實體框架 - 程式碼優先遷移
實體框架 4.3 包含一個新的程式碼優先遷移功能,允許您隨著模型隨時間變化而逐步發展資料庫模式。對於大多數開發者來說,這比 4.1 和 4.2 版本中需要您手動更新資料庫或在模型更改時刪除並重新建立資料庫的資料庫初始化程式選項有了很大的改進。
在實體框架 4.3 之前,如果您已經在資料庫中擁有資料(種子資料除外)或現有的儲存過程、觸發器等,這些策略都會刪除整個資料庫並重新建立它,因此您會丟失資料和其他資料庫物件。
透過遷移,當您的模型發生更改時,它將自動更新資料庫模式,而不會丟失任何現有資料或其他資料庫物件。
它使用一個名為 MigrateDatabaseToLatestVersion 的新的資料庫初始化程式。
遷移有兩種型別:
- 自動遷移
- 基於程式碼的遷移
自動遷移
自動遷移首先在實體框架 4.3 中引入。在自動遷移中,您不需要在程式碼檔案中手動處理資料庫遷移。例如,對於每次更改,您還需要更改域類。但是,使用自動遷移,您只需在程式包管理器控制檯中執行一個命令即可完成此操作。
讓我們看一下自動遷移的分步過程。
當您使用程式碼優先方法時,您的應用程式沒有資料庫。
在這個例子中,我們將從三個基本類開始,例如學生、課程和註冊,如下程式碼所示。
public class Enrollment {
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
public class Student {
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
public class Course {
public int CourseID { get; set; }
public string Title { get; set; }
[Index]
public int Credits { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
以下是上下文類。
public class MyContext : DbContext {
public MyContext() : base("MyContextDB") {}
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Enrollment> Enrollments { get; set; }
public virtual DbSet<Student> Students { get; set; }
}
在執行應用程式之前,您需要啟用自動遷移。
步驟 1 - 從工具 → NuGet 程式包管理器 → 程式包管理器控制檯開啟程式包管理器控制檯。
步驟 2 - 要啟用自動遷移,請在程式包管理器控制檯中執行以下命令。
PM> enable-migrations -EnableAutomaticMigrations:$true
步驟 3 - 命令成功執行後,它會在專案的 Migration 資料夾中建立一個內部密封的 Configuration 類,如下程式碼所示。
namespace EFCodeFirstDemo.Migrations {
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<EFCodeFirstDemo.MyContext> {
public Configuration() {
AutomaticMigrationsEnabled = true;
ContextKey = "EFCodeFirstDemo.MyContext";
}
protected override void Seed(EFCodeFirstDemo.MyContext context) {
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
// context.People.AddOrUpdate(
// p ⇒ p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
}
}
}
步驟 4 - 使用新的資料庫初始化策略 MigrateDatabaseToLatestVersion 在上下文類中設定資料庫初始化程式。
public class MyContext : DbContext {
public MyContext() : base("MyContextDB") {
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext,
EFCodeFirstDemo.Migrations.Configuration>("MyContextDB"));
}
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Enrollment> Enrollments { get; set; }
public virtual DbSet<Student> Students { get; set; }
}
步驟 5 - 您已設定自動遷移。當您執行應用程式時,當您更改模型時,它會自動處理遷移。
步驟 6 - 正如您所看到的,一個系統表 __MigrationHistory 也與其他表一起在您的資料庫中建立。在 __MigrationHistory 中,自動遷移維護資料庫更改的歷史記錄。
步驟 7 - 當您新增另一個實體類作為您的域類並執行您的應用程式時,它將在您的資料庫中建立該表。讓我們新增以下 StudentLogIn 類。
public class StudentLogIn {
[Key, ForeignKey("Student")]
public int ID { get; set; }
public string EmailID { get; set; }
public string Password { get; set; }
public virtual Student Student { get; set; }
}
步驟 8 - 不要忘記在您的上下文類中新增上面提到的類的 DBSet,如下程式碼所示。
public virtual DbSet<StudentLogIn> StudentsLogIn { get; set; }
步驟 9 - 再次執行您的應用程式,您將看到 StudentsLogIn 表已新增到您的資料庫中。
上面提到的自動遷移步驟僅適用於您的實體。例如,要新增另一個實體類或刪除現有實體類,它將成功遷移。但是,如果您向實體類新增或刪除任何屬性,它將引發異常。
步驟 10 - 要處理屬性遷移,您需要在 configuration 類建構函式中設定 AutomaticMigrationDataLossAllowed = true。
public Configuration() {
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
ContextKey = "EFCodeFirstDemo.MyContext";
}
基於程式碼的遷移
當您開發新應用程式時,您的資料模型會頻繁更改,每次模型更改時,它都會與資料庫不同步。您已將實體框架配置為每次更改資料模型時自動刪除和重新建立資料庫。當您想要更多地控制遷移時,基於程式碼的遷移非常有用。
當您新增、刪除或更改實體類或更改您的 DbContext 類時,下次執行應用程式時,它會自動刪除您現有的資料庫,建立一個與模型匹配的新資料庫,並使用測試資料對其進行填充。
程式碼優先遷移功能透過啟用程式碼優先更新資料庫模式而不是刪除和重新建立資料庫來解決此問題。要部署應用程式,您必須啟用遷移。
以下是遷移資料庫更改的基本規則:
- 啟用遷移
- 新增遷移
- 更新資料庫
讓我們看一下基於程式碼的遷移的分步過程。
當您使用程式碼優先方法時,您的應用程式沒有資料庫。
在這個例子中,我們將再次從三個基本類開始,例如學生、課程和註冊,如下程式碼所示。
public class Enrollment {
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
public class Student {
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
public class Course {
public int CourseID { get; set; }
public string Title { get; set; }
[Index]
public int Credits { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
以下是上下文類。
public class MyContext : DbContext {
public MyContext() : base("MyContextDB") {
Database.SetInitializer(new MigrateDatabaseToLatestVersion<
MyContext, EFCodeFirstDemo.Migrations.Configuration>("MyContextDB"));
}
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Enrollment> Enrollments { get; set; }
public virtual DbSet<Student> Students { get; set; }
}
步驟 1 - 在執行應用程式之前,您需要啟用遷移。
步驟 2 - 從工具 → NuGet 程式包管理器 → 程式包管理器控制檯開啟程式包管理器控制檯。
步驟 3 - 遷移已啟用,現在透過執行以下命令在您的應用程式中新增遷移。
PM> add-migration "UniDB Schema"
步驟 4 - 命令成功執行後,您將看到在 Migration 資料夾中建立了一個新檔案,其名稱是您傳遞給命令的引數加上時間戳字首,如下圖所示。
步驟 5 - 您可以使用“update-database”命令建立或更新資料庫。
PM> Update-Database -Verbose
“-Verbose”標誌指定在控制檯中顯示應用於目標資料庫的 SQL 語句。
步驟 6 - 讓我們在學生類中新增另一個屬性“年齡”,然後執行更新語句。
public class Student {
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public int Age { get; set; }
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
當您執行 PM → Update-Database –Verbose 時,命令成功執行後,您將看到新列 Age 已新增到您的資料庫中。
我們建議您逐步執行上述示例,以便更好地理解。