一. 反向工程 反向工程是基於資料庫架構,生成的實體類和DbContext類代碼的過程,對於Visual Studio開發,建議使用PMC。對於其他開發環境,請選擇.NET Core CLI工具(跨平臺)。 (1) 在程式包管理器控制台(PMC)工具中使用命令Scaffold-DbContext 來 ...
一. 反向工程
反向工程是基於資料庫架構,生成的實體類和DbContext類代碼的過程,對於Visual Studio開發,建議使用PMC。對於其他開發環境,請選擇.NET Core CLI工具(跨平臺)。
(1) 在程式包管理器控制台(PMC)工具中使用命令Scaffold-DbContext 來進行反向工程。
(2) 在.NET 命令行介面 (CLI) 工具中使用dotnet ef dbcontext scaffold命令來進行反向工程。
1.1 Scaffold-DbContext
介紹
使用Scaffold-DbContext命令生成實體類型時,資料庫表必須具有主鍵,沒有主鍵的表不會被反向工程。下麵是PMC下的參數表格介紹,對於CLI的scaffold參數介紹參考官網
參數 |
描述 |
-Connection <String> | 資料庫的連接字元串。該參數,是必需的。 |
-Provider <String> | 要使用的提供程式。通常,這是NuGet包的名稱,例如:Microsoft.EntityFrameworkCore.SqlServer 。該參數,是必需的。 |
-OutputDir <String> | 放入文件的目錄。路徑是相對於項目目錄的。 |
-ContextDir <String> | 放置DbContext 文件的目錄。路徑是相對於項目目錄的。 |
-Context <String> | DbContext 要生成的類的名稱。 |
-Schemas <String []> | 用於生成實體類型的表的架構。如果省略此參數,則包括所有架構。例如在sqlserver上預設dbo架構 |
-Tables <String []> | 用於生成實體類型的表。如果省略此參數,則包括所有表。 |
-DataAnnotations | 使用屬性配置模型(如果可能)。如果省略此參數,則僅使用fluent API。 |
-UseDatabaseNames |
使用與資料庫中顯示的完全相同的表和列名稱。如果省略此參數,則更改資料庫名稱以更符合C#名稱樣式約定。 |
-Force | 覆蓋現有文件 |
二. 命令參數詳解
2.1 必備參數
-Connection <String>是第一個參數是資料庫的連接字元串。 工具將使用此連接字元串來讀取資料庫架構。-Provider <String>是提供程式名稱。
// PowerShell Scaffold-DbContext 'Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook' Microsoft.EntityFrameworkCore.SqlServer // dotnet dotnet ef dbcontext scaffold "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook" Microsoft.EntityFrameworkCore.SqlServer
2.2 指定表和架構
預設情況下,資料庫架構中的所有表都被反向工程到實體類型,可以限制哪些表是反向工程,處理通過指定架構和表。
-Schemas
在 PMC 中的參數和—schema
CLI 中的選項可用於包含在架構中的每個表。
-Tables
(PMC) 和--table
(CLI) 可用於包括特定的表。
若要在 PMC 中包含多個表,使用一個數組。若要在 CLI 中包含多個表,請多次指定選項。
// PowerShell Scaffold-DbContext ... -Tables Blog, Post // dotnet dotnet ef dbcontext scaffold ... --table Blog --table Post
2.3 保留名稱
預設情況下,資料庫的表名稱和列名稱是固定的,以便更好地匹配實體名稱和屬性名稱的.NET命名約定。在PMC中指定 -UseDatabaseNames
或在CLI中指定 --use-database-names
,
使數據模型中的實體名稱和屬性名稱與資料庫中顯示的的表和列名稱完全相同。如果省略此參數,則可能會更改名稱以更符合C#命名約定。
2.4 Fluent API 或數據註釋
預設情況下,使用Fluent API配置實體類型。在PMC中指定
-DataAnnotations
或在CLI中指定 --data-annotations
的情況下使用數據註釋。下麵二個代碼塊, 一個是使用Fluent API配置的,一個是使用數據註釋,二者實現功能上一樣。
//Fluent API配置 entity.Property(e => e.Title) .IsRequired() .HasMaxLength(160); //數據註釋 [Required] [StringLength(160)] public string Title { get; set; }
2.5 DbContext 名稱
預設情況下,DbContext 上下文名稱是(資料庫名+ Context尾碼)。 若要自定義一個DbContext 上下文名稱,在PMC中指定 -Context
或在CLI中指定--context
。
2.6 目錄和命名空間
預設情況下,實體類和DbContext類被搭建到項目的根目錄中,並使用項目的預設命名空間。在PMC中指定-OutputDir
或在CLI中指定--output-dir
將
指定目錄。命名空間將是根命名稱+子目錄的名稱。
下麵使用-ContextDir
(PMC) 和--context-dir
(CLI) 來創建到一個單獨的目錄(Models),存放實體類和DbContext 類。
// PowerShell Scaffold-DbContext ... -ContextDir Data -OutputDir Models
// dotnet dotnet ef dbcontext scaffold ... --context-dir Data --output-dir Models
2.7 更新模型
當更改資料庫後,可能需要更新EF Core模型以反映這些更改。如果資料庫更改很簡單,則最簡單的方法是手動對EF Core模型進行更改。例如,重命名錶或列,刪除列或更新列的類型是在代碼中進行的微不足道的更改。如果,資料庫更改動作大。一個常見的工作流程是使用-Force
(PMC)或--force
(CLI)再次從資料庫對模型進行反向工程,以使用更新的模型覆蓋現有模型。
三.演示
3.1 初始化反向工程
下麵來演示一下,關於準備工作和反向工程註意事項這裡不在說明,請參考“asp.net core 系列 21 EF現有資料庫進行反向工程”。
本篇使用Visual Studio開發,使用Package Manager Console工具來進行反向工程管理,用PowerShell腳本,並附帶上跨平臺管理 的dotnet命令,基於EFGetStarted.AspNetCore.NewDb資料庫,包括:Blogs和Posts表來演示反向工程。如下圖所示:
PM> Scaffold-DbContext "Data Source ={ip};Initial Catalog = EFGetStarted.AspNetCore.NewDb; User ID = hsr;Password =js*2015;" Microsoft.EntityFrameworkCore.SqlServer
-OutputDir Models -Tables Blogs -Context ReverseDbContext -DataAnnotations -UseDatabaseNames
上面的一串命令參數中,除了資料庫的連接字元串、使用的提供程式、放入文件的目錄,其它參數都是可選的。 命令執行成功後,將把DbContext 上下文和實體類(Blogs)存放到Models文件夾中。 使用了 -Context自定義DbContext 上下文、-DataAnnotations數據註釋代替Fluent API配置、 -UseDatabaseNames與資料庫中顯示的的表和列名稱完全相同。
3.2 更新模型
下麵將Blogs表的Url欄位類型長度從Max改為400,新增了Address欄位,使用-Force
來覆蓋現有文件。命令成功後,查看
Blogs
實體。
PM> Scaffold-DbContext "Data Source =172.168.16.75;Initial Catalog = EFGetStarted.AspNetCore.NewDb; User ID = hsr;Password =js*2015;" Microsoft.EntityFrameworkCore.SqlServer
-OutputDir Models -Tables Blogs -Context ReverseDbContext -DataAnnotations -UseDatabaseNames -Force
四. 其它說明
4.1 反向工程工作原理
(1) 反向工程開始時讀取資料庫架構。 它將讀取有關表、 列、 約束和索引的信息。
(2) 接下來,它使用的架構信息創建 EF Core 模型。 使用表來創建實體類型;使用列來創建屬性;和外鍵用於創建關係。
(3) 最後,該模型用於生成代碼。 相應的實體類型的類、 Fluent API 和數據批註已搭建基架以重新創建相同的模型從您的應用程式中。
4.2 反向工程哪些不起作用
(1) 並非所有關於模型的內容都可以使用資料庫架構來表示。 例如:有關繼承層次結構,擁有類型,表拆分等不存在於資料庫架構中。 因此,這些構造將永遠不能反向工程處理。
此外,EF Core提供程式可能不支持某些列類型。這些列不會包含在模型中。
(2) EF Core需要每個實體類型有一個主鍵。 表沒有主鍵是會反向工程。
(3) 您可以定義併發標記EF Core 模型以防止兩個用戶在同一時間更新同一實體中。 有些資料庫可以代替這種併發衝突,例如SQL Server 中的行版本控制。但是這也不能反向工程處理。
4.3 反向工程自定義模型
EF Core生成的代碼可隨意改變它。只有再次對同一模型進行反向工程時,才會重新生成它。Scaffold代碼代表一個可用於訪問資料庫的模型,但它肯定不是唯一可以使用的模型。
可以自定義實體類和DbContext類以滿足您的需要。例如,可以選擇重命名類型和屬性,引入繼承層次結構或將表拆分為多個實體。您還可以從模型中刪除非唯一索引,未使用的序列和導航屬性,可選標量屬性和約束名稱。還可以在單獨的文件中使用另一個partial 類添加其他構造函數,方法,屬性等。即使您打算再次對模型進行逆向工程,這種方法仍然有效。
參考文獻