asp.net core系列 31 EF管理數據庫架構--必備知識 反向工程


一.   反向工程

  反向工程是基於數據庫架構,生成的實體類和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 類添加其他構造函數,方法,屬性等。即使您打算再次對模型進行逆向工程,這種方法仍然有效。

 

  參考文獻

     EF反向工程


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM