ASP.NET Core 中的 Razor 頁面和 EF Core - 遷移

2019-04-17 08:58 更新

Contoso University Web 應(yīng)用演示了如何使用 EF Core 和 Visual Studio 創(chuàng)建 Razor 頁面 Web 應(yīng)用。若要了解系列教程,請參閱第一個教程

本教程使用 EF Core 遷移功能管理數(shù)據(jù)模型更改。

如果遇到無法解決的問題,請下載已完成應(yīng)用。

開發(fā)新應(yīng)用時,數(shù)據(jù)模型會頻繁更改。 每當(dāng)模型發(fā)生更改時,都無法與數(shù)據(jù)庫進(jìn)行同步。 本教程首先配置 Entity Framework 以創(chuàng)建數(shù)據(jù)庫(如果不存在)。 每當(dāng)數(shù)據(jù)模型發(fā)生更改時:

  • DB 都會被刪除。
  • EF 都會創(chuàng)建一個新數(shù)據(jù)庫來匹配該模型。
  • 應(yīng)用使用測試數(shù)據(jù)為 DB 設(shè)定種子。

這種使 DB 與數(shù)據(jù)模型保持同步的方法適用于多種情況,但將應(yīng)用部署到生產(chǎn)環(huán)境的情況除外。 當(dāng)應(yīng)用在生產(chǎn)環(huán)境中運(yùn)行時,應(yīng)用通常會存儲需要保留的數(shù)據(jù)。 每當(dāng)發(fā)生更改(例如添加新列)時,應(yīng)用都無法在具有測試 DB 的環(huán)境下啟動。 EF Core 遷移功能可通過使 EF Core 更新 DB 架構(gòu)而不是創(chuàng)建新 DB 來解決此問題。

數(shù)據(jù)模型發(fā)生更改時,遷移將更新架構(gòu)并保留現(xiàn)有數(shù)據(jù),而無需刪除或重新創(chuàng)建 DB。

刪除數(shù)據(jù)庫

使用 SQL Server 對象資源管理器 (SSOX) 或 database drop 命令:

在“包管理器控制臺”(PMC) 中運(yùn)行以下命令:

PMC
Drop-Database

從 PMC 運(yùn)行 Get-Help about_EntityFrameworkCore,獲取幫助信息。

創(chuàng)建初始遷移并更新 DB

生成項(xiàng)目并創(chuàng)建第一個遷移。

PMC
Add-Migration InitialCreate
Update-Database

了解 Up 和 Down 方法

EF Core migrations add 命令已生成用于創(chuàng)建 DB 的代碼。 此遷移代碼位于 Migrations<timestamp>_InitialCreate.cs 文件中。 InitialCreate 類的 Up 的方法創(chuàng)建與數(shù)據(jù)模型實(shí)體集相對應(yīng)的 DB 表。 Down 方法刪除這些表,如下例所示:

C#

public partial class InitialCreate : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Course",
            columns: table => new
            {
                CourseID = table.Column<int>(nullable: false),
                Title = table.Column<string>(nullable: true),
                Credits = table.Column<int>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Course", x => x.CourseID);
            });

        migrationBuilder.CreateTable(
    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Enrollment");

        migrationBuilder.DropTable(
            name: "Course");

        migrationBuilder.DropTable(
            name: "Student");
    }
}

遷移調(diào)用 Up 方法為遷移實(shí)現(xiàn)數(shù)據(jù)模型更改。 輸入用于回退更新的命令時,遷移調(diào)用 Down 方法。

前面的代碼適用于初始遷移。 該代碼是運(yùn)行 migrations add InitialCreate 命令時創(chuàng)建的。 遷移名稱參數(shù)(本示例中為“InitialCreate”)用于指定文件名。 遷移名稱可以是任何有效的文件名。 最好選擇能概括遷移中所執(zhí)行操作的字詞或短語。 例如,添加了系表的遷移可稱為“AddDepartmentTable”。

如果創(chuàng)建了初始遷移并且存在 DB:

  • 會生成 DB 創(chuàng)建代碼。
  • DB 創(chuàng)建代碼不需要運(yùn)行,因?yàn)?DB 已與數(shù)據(jù)模型相匹配。 即使 DB 創(chuàng)建代碼運(yùn)行也不會做出任何更改,因?yàn)?DB 已與數(shù)據(jù)模型相匹配。

如果將應(yīng)用部署到新環(huán)境,則必須運(yùn)行 DB 創(chuàng)建代碼才能創(chuàng)建 DB。

先前刪除了 DB,因此已不存在,所以遷移會創(chuàng)建新的 DB。

數(shù)據(jù)模型快照

遷移在 Migrations/SchoolContextModelSnapshot.cs 中創(chuàng)建當(dāng)前數(shù)據(jù)庫架構(gòu)的快照。 添加遷移時,EF 會通過將數(shù)據(jù)模型與快照文件進(jìn)行對比來確定已更改的內(nèi)容。

若要刪除遷移,請使用以下命令:

Remove-Migration

刪除遷移命令會刪除遷移并確保正確重置快照。

刪除 EnsureCreated 并測試應(yīng)用

早期開發(fā)使用了 EnsureCreated。 本教程將使用遷移。 EnsureCreated 具有以下限制:

  • 繞過遷移并創(chuàng)建 DB 和架構(gòu)。
  • 不會創(chuàng)建遷移表。
  • 不能與遷移一起使用。
  • 專門用于在頻繁刪除并重新創(chuàng)建 DB 的情況下進(jìn)行測試或快速制作原型。

刪除 EnsureCreated:

C#

context.Database.EnsureCreated();

運(yùn)行應(yīng)用并驗(yàn)證 DB 設(shè)定為種子。

檢查數(shù)據(jù)庫

使用 SQL Server 對象資源管理器檢查 DB。 請注意,增加了 __EFMigrationsHistory 表。 __EFMigrationsHistory 表跟蹤已應(yīng)用到 DB 的遷移。 查看 __EFMigrationsHistory 表中的數(shù)據(jù),其中顯示對應(yīng)初始遷移的一行數(shù)據(jù)。 上面的 CLI 輸出示例中最后部分的日志顯示了創(chuàng)建此行的 INSERT 語句。

運(yùn)行應(yīng)用并驗(yàn)證一切正常運(yùn)行。

在生產(chǎn)環(huán)境中應(yīng)用遷移

不建議生產(chǎn)應(yīng)用在應(yīng)用程序啟動時調(diào)用 Database.Migrate。 不應(yīng)從服務(wù)器場中的應(yīng)用調(diào)用 Migrate。 例如,已將應(yīng)用在云中部署為橫向擴(kuò)展(運(yùn)行應(yīng)用的多個示例)的情況。

應(yīng)在部署過程中以受控的方式執(zhí)行數(shù)據(jù)庫遷移。 生產(chǎn)數(shù)據(jù)庫遷移方法包括:

  • 使用遷移創(chuàng)建 SQL 腳本,并在部署過程中使用 SQL 腳本。
  • 在受控的環(huán)境中運(yùn)行 dotnet ef database update。

EF Core 使用 __MigrationsHistory 表查看是否需要運(yùn)行任何遷移。 如果 DB 已是最新,則無需運(yùn)行遷移。

疑難解答

下載已完成應(yīng)用。

應(yīng)用會生成以下異常:

text

SqlException: Cannot open database "ContosoUniversity" requested by the login.
The login failed.
Login failed for user 'user name'.

解決方案:運(yùn)行 dotnet ef database update


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號