反向工程是基于数据库架构,生成的实体类和DbContext类代码的过程,对于Visual Studio开发,建议使用PMC。对于其余开发环境,请选择.NET Core CLI工具(跨平台)。sql
(1) 在程序包管理器控制台(PMC)工具中使用命令Scaffold-DbContext 来进行反向工程。数据库
(2) 在.NET 命令行接口 (CLI) 工具中使用dotnet ef dbcontext scaffold命令来进行反向工程。数组
1.1 Scaffold-DbContext
介绍
架构
使用Scaffold-DbContext命令生成实体类型时,数据库表必须具备主键,没有主键的表不会被反向工程。下面是PMC下的参数表格介绍,对于CLI的scaffold参数介绍参考官网并发
参数asp.net |
描述ide |
-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>是提供程序名称。sqlserver
// 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 类添加其余构造函数,方法,属性等。即便您打算再次对模型进行逆向工程,这种方法仍然有效。
参考文献