利用 dotnet ef 指令依據資料庫定義產生 Entity Framework Core 資料庫實體定義程式碼(DB First)

使用 Entity Framework Core 主要有兩種開發方式,程式碼優先(Code First)和資料庫優先(Database First)。程式碼優先是直接在程式中建立資料庫實體模型( Entity Model),然後使用指令利用模型建立資料庫中的資料表等內容。而資料庫優先則相反,是利用資料庫的內容產生模型程式碼。

什麼情況下會資料庫優先?通常大型的專案都會有資料庫管理員(DBA),DBA 定義好資料庫後我們就可以很方便的使用 dotnet ef dbcontext scaffold 指令產生資料庫對應的實體程式碼,省去我們很多煩惱,不用像程式碼優先那樣還要自己定義。

安裝 dotnet ef 工具

全域安裝 dotnet ef 工具:
    
dotnet tool install --global dotnet-ef
    

更新已安裝的 dotnet ef 工具:
    
dotnet tool update --global dotnet-ef
    

如果出現以下錯誤訊息,就代表沒有安裝 dotnet ef 工具,請再次執行上面的 dotnet tool install --global dotnet-ef 指令安裝:
  
dotnet ef dbcontext scaffold "Server=192.168.0.100,1433;Database=my_database;User=ruyut;Password=Abcd1234;Trusted_Connection=False;TrustServerCertificate=true;" Microsoft.EntityFrameworkCore.SqlServer -d -o Data/Entities
無法執行,因為找不到指定的命令或檔案。
可能的原因包括:
 * 您拼錯了內建 dotnet 命令。
 * 您打算執行 .NET 程式,但 dotnet-ef 不存在。
 * 您打算執行全域工具,但在 PATH 上找不到具有此名稱的以 dotnet 為首碼的可執行檔。


建立基礎 Entity Framework Core 程式碼

本文是產生 Entity Framework Core 的資料庫實體程式碼,所以這裡是假設專案已經安裝 Entity Framework Core 套件的情況下,如果沒有請先使用 NuGet 安裝 Microsoft.EntityFrameworkCore 相關套件。
本文使用 SQL Server 示範,如果是和本文一樣,則只需要安裝 Microsoft.EntityFrameworkCore.SqlServer 套件即可。
為了避免其他問題,筆者這裡簡單的帶過最基本使用 Entity Framework Core 的方式

在 appsettings.json 中加入 ConnectionStrings > DefaultConnection ,設定好連接資訊
    
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "Server=192.168.0.100,1433;Database=my_database;User=ruyut;Password=Abcd1234;Trusted_Connection=False;TrustServerCertificate=true;"
  },
  "AllowedHosts": "*"
}

    

在 ASP.NET Core 專案中要在 Program.cs 中加入下面的程式碼:
    
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
    options.UseSqlServer(connectionString);
});
    
var app = builder.Build();
    

建立 ApplicationDbContext.cs ,通常會放在 Data 資料夾中
    
public class ApplicationDbContext : DbContext
{
    protected ApplicationDbContext()
    {
    }

    public ApplicationDbContext(DbContextOptions options) : base(options)
    {
    }
}
    

這個 ApplicationDbContext.cs 是第一次同步時需要使用的,後面使用指令同步時應該會自動產生 ApplicationDbContext.cs 檔案,後續都自動產生的 ApplicationDbContext.cs 即可,就不會再需要自己建立的這個 ApplicationDbContext.cs 了。

使用 dotnet ef dbcontext scaffold 指令

基礎指令:
  • dotnet ef dbcontext scaffold: 基礎指令
  • "Server=192.168.0.100.....": 資料庫連接字串
  • Microsoft.EntityFrameworkCore.SqlServer: 使用 SqlServer 資料庫
  • -d: 以屬性的方式定義資料庫實體,不產生額外設定檔
  • -o Entities: 資料庫實體放置路徑,可以包含資料夾,例如 Data 資料夾下的 Entities 資料夾內
    
dotnet ef dbcontext scaffold "Server=192.168.0.100,1433;Database=my_database;User=ruyut;Password=Abcd1234;Trusted_Connection=False;TrustServerCertificate=true;" Microsoft.EntityFrameworkCore.SqlServer -d -o Data/Entities
    

假設我們有在 appsettings.json 中定義資料庫連接字串,在使用指令時就只要使用 Name 指定連接字串即可。
    
dotnet ef dbcontext scaffold Name=ConnectionStrings:DefaultConnection Microsoft.EntityFrameworkCore.SqlServer -d -o Data/Entities
    

但是這樣會建立新的 DbContext 類別,我們需要使用 --context 參數來指定為我們已經建立的 ApplicationDbContext.cs
    
dotnet ef dbcontext scaffold Name=ConnectionStrings:DefaultConnection Microsoft.EntityFrameworkCore.SqlServer -d --context ApplicationDbContext -o Data/Entities
    

若 ApplicationDbContext.cs 不是放在專案根目錄下,則需要使用 --context-dir 參數來指定,例如是 Data/Contexts/ApplicationDbContext.cs ,則:
    
dotnet ef dbcontext scaffold Name=ConnectionStrings:DefaultConnection Microsoft.EntityFrameworkCore.SqlServer -d --context-dir Data/Contexts --context ApplicationDbContext -o Data/Entities
    

假設資料庫欄位有變更,需要重新產生資料庫實體物件,則可以附加 -f 參數,覆蓋先前產生的檔案:
    
dotnet ef dbcontext scaffold Name=ConnectionStrings:DefaultConnection Microsoft.EntityFrameworkCore.SqlServer -d --context-dir Data/Contexts --context ApplicationDbContext -o Data/Entities -f
    



參考資料:
Microsoft.Learn - Entity Framework Core tools reference - .NET Core CLI

留言