天天看點

EFCore之指令行工具

介紹

EFCore工具可幫助完成設計資料庫時候的開發任務,主要用于通過對資料庫架構進行反向工程來管理遷移和搭建DbContext和實體類型。EFCore .NET指令行工具是對跨平台.NET Core CLI工具的擴充,該工具執行需要具有.NET Core SDK(具有 Sdk="Microsoft.NET.Sdk" 的項目或項目檔案中的相似項目)的項目,優點是适用于所有平台。

安裝工具

使用終端工具執行在任意目錄執行下面指令,可以嘗試下Terminal終端工具。

# 安裝為全局工具
dotnet tool install --global dotnet-ef

# 更新工具
dotnet tool update --global dotnet-ef
           

驗證安裝

dotnet ef
           
EFCore之指令行工具

參考位址:https://docs.microsoft.com/zh-cn/ef/core/cli/dotnet

建立項目

本次使用的項目為.NetCore WebAPI項目,代碼結構如下

EFCore之指令行工具
源代碼位址:https://gitee.com/AZRNG/my-example

遷移代碼優先

簡單遷移

使用遷移還需要另外安裝Nuget包

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.6" />
           

在項目檔案夾目錄下操作終端工具

dotnet ef migrations add Init

//  指定Migrations目錄
dotnet ef migrations add Init --output-dir MyMigration

// 指定遷移上下文
dotnet ef migrations add Init --context BlogContext
           
在 EF Core 5.0及以上 中,才可以使用更改獨立于目錄的命名空間 --namespace 。

此處Init為遷移名稱,該名稱要可以表示出目前遷移的内容資訊。

EFCore之指令行工具

生成成功,檢視項目内的變化,增加了一個檔案夾Migrations

EFCore之指令行工具

xxxxxx_Init -主遷移檔案。包含應用遷移的操作(在up中)和還原遷移所需的操作(在down中)

OpenDbContextModelSnapshot -目前模型的快照。用于确定添加下一遷移時的更改内容。

最好檢查下生成的内容是不是我們期望的那樣子,有些情況下是需要進行修改的。

如果這個時候,我們又修改了實體類,那麼還可以運作指令再次遷移(遷移名稱不能相同)

特殊情況

有些特殊情況下生成的遷移檔案不是我們預期的那樣子,這個時候需要手動修改。

列名重命名

如果實體類中的列明重複了,我們重新遷移,檢視生成的檔案,比如我将使用者表Account修改為UserName,按照官網的說法會生成一下遷移

migrationBuilder.DropColumn(
    name: "Account",
    table: "User");

migrationBuilder.AddColumn<string>(
    name: "UserName",
    table: "User",
    nullable: true);
           

實際生成結果為

migrationBuilder.RenameColumn(
        name: "Account",
        table: "user",
        newName: "UserName");
           

如果生成了先Drop再Add那種進行應用資料庫,則使用者的帳号都會丢失,是以需要修改我下面這種。(目前現在生成的就是我們想要樣子,不過我們還需要謹慎)

還有其他的情況需要注意,可以參考官網

删除遷移

有時候我們在添加遷移後,馬上有實體進行改動,這個時候我們并不像再次生成遷移,那麼就可以考慮删除上個遷移。

dotnet ef migrations remove
           

删除遷移後,對實體進行更改,然後再次添加遷移。特殊情況下我們想删除所有的遷移,可以通過删除遷移檔案夾并删除資料庫來完成。

場景:我們已經生成了許多遷移檔案,比較繁瑣,我們想将這些遷移檔案合并,那麼就可以删除遷移檔案夾,然後删除資料庫的遷移曆史表資料,再次生成遷移,根據生成的遷移名稱,對遷移曆史記錄表增加一條對應的資料。

列出遷移

通過下面指令可以查詢到我們所有的遷移

dotnet ef migrations list
           
EFCore之指令行工具

生成SQL腳本

生成從0到最新遷移的SQL腳本

dotnet ef migrations script
           
EFCore之指令行工具

From

生成從給定遷移到最新遷移的SQL腳本(包含最新遷移)

dotnet ef migrations script AddNewTables
           

From和To

可以從指定的From遷移到指定遷移To的SQL腳本

dotnet ef migrations script AddNewTables AddAuditTable
           

腳本生成接受以下兩個參數,以訓示應生成的遷移範圍:

  • from 遷移應是運作該腳本前應用到資料庫的最後一個遷移。 如果未應用任何遷移,請指定 (預設值)。
  • to 遷移是運作該腳本後應用到資料庫的最後一個遷移。 它預設為項目中的最後一個遷移。

建立資料庫和表

手動執行

讓EFCore建立資料庫并從遷移中建立表結構,運作指令

dotnet ef database update
           
EFCore之指令行工具

如果後續我們實體類結構再有修改,那麼還可以先建立遷移檔案,然後再生成到資料庫。(因為EF已經檢測到資料庫已存在,會通過對比特殊遷移曆史記錄表,然後隻應用那些新的遷移)。

運作時候執行

//如果目前資料庫不存在按照目前 model 建立,如果存在則将資料庫調整到和目前 model 比對
dbContext.Database.Migrate(); // 生産環境使用考慮好資料問題
           
請勿在 Migrate() 前調用 EnsureCreated()。 EnsureCreated() 會繞過遷移建立架構,這會導緻 Migrate() 失敗

建立和删除API

EnsureDeleted

EnsureDeleted 方法會删除資料庫(如果存在)。 如果你沒有相應的權限,則會引發異常。

// Drop the database if it exists
dbContext.Database.EnsureDeleted();
           

EnsureCreated

如果資料庫不存在,EnsureCreated 将建立資料庫并初始化資料庫架構。 如果存在任何表 (包括其他 DbContext 類) 的表,則不會初始化該架構。

// Create the database if it doesn't exist
dbContext.Database.EnsureCreated();
           

SQL 腳本

若要擷取 EnsureCreated 使用的 SQL,可以使用 GenerateCreateScript 方法。

var sql = dbContext.Database.GenerateCreateScript();
           

多個 DbContext 類

EnsureCreated 僅在資料庫中不存在任何表時有效。 如果需要,您可以編寫自己的檢查來檢視是否需要初始化架構,并使用基礎 IRelationalDatabaseCreator 服務來初始化架構。

// TODO: Check whether the schema needs to be initialized

// Initialize the schema for this DbContext
var databaseCreator = dbContext.GetService<IRelationalDatabaseCreator>();
databaseCreator.CreateTables();
           
參考位址:https://docs.microsoft.com/zh-cn/ef/core/managing-schemas/ensure-created

反向工程資料庫優先

dotnet ef dbcontext scaffold "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook" Microsoft.EntityFrameworkCore.SqlServer
           

配置資料庫連接配接字元串、資料庫提供程式

常用配置

--table 指定表反向工程

--context 指定上下文

-context-dir 指定上下文目錄

--output-dir Models 指定上下文目錄

示例:目前我們有一個資料庫檔案,需要通過反向工程生成實體類,表結構如下

user

EFCore之指令行工具

score

EFCore之指令行工具

項目結構如下

EFCore之指令行工具

項目目錄使用終端執行指令

dotnet ef dbcontext scaffold "Server=localhost;Database=test;Port=3306;charset=utf8;uid=root;pwd=123456;" Pomelo.EntityFrameworkCore.MySql --output-dir Entity  --context OpenDbContext
           
EFCore之指令行工具
EFCore之指令行工具
不過反向工程這種并不會将資料庫表注釋帶到代碼中,并且每次執行時候會删除原來的表結構。

參考文檔

開始遷移:https://docs.microsoft.com/zh-cn/ef/core/managing-schemas/migrations/managing?tabs=dotnet-core-cli

自定義曆史記錄表:https://docs.microsoft.com/zh-cn/ef/core/managing-schemas/migrations/history-table

微信公衆号

EFCore之指令行工具