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(); //数据注释
[Required]
[StringLength()]
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 类添加其他构造函数,方法,属性等。即使您打算再次对模型进行逆向工程,这种方法仍然有效。
参考文献
asp.net core系列 31 EF管理数据库架构--必备知识 反向工程的更多相关文章
- asp.net core系列 30 EF管理数据库架构--必备知识 迁移
一.管理数据库架构概述 EF Core 提供两种主要方法来保持 EF Core 模型和数据库架构同步.一是以 EF Core 模型为基准,二是以数据库为基准. (1)如果希望以 EF Core 模型为 ...
- asp.net core 系列 21 EF现有数据库进行反向工程
一.概述 在上篇中使用EF基于数据模型创建数据库, 本篇继续使用 EF 基于数据库创建数据模型. 实现对已有数据库进行反向工程,来构建数据访问的 ASP.NET Core MVC 应用程序.已有 ...
- asp.net core 系列 22 EF(连接字符串,连接复原,DbContext)
一.连接字符串 在上二篇中,ASP.NET Core 应用程序连接字符串是写死在ConfigureServices代码中,下面介绍通过配置来实现.连接字符串可以存储在 appsettings.json ...
- asp.net core 系列 20 EF基于数据模型创建数据库
一.概述 本章使用 Entity Framework Core 构建执行基本数据访问的 ASP.NET Core MVC 应用程序.使用迁移(migrations)基于数据模型创建数据库,是一种cod ...
- asp.net core系列 29 EF模型配置(查询类型,关系数据库建模)
一.查询类型 此功能是EF Core 2.1中的新功能. EF Core除了实体类型之外,EF Core模型还可以包含查询类型,这些查询类型是针对“未映射到实体类型”的数据获取.比如视图,或只读数据表 ...
- asp.net core系列 28 EF模型配置(字段,构造函数,拥有实体类型)
一. 支持字段 EF允许读取或写入字段而不是一个属性.在使用实体类时,用面向对象的封装来限制或增强应用程序代码对数据访问的语义时,这可能很有用.无法使用数据注释配置.除了约定,还可以使用Fluent ...
- asp.net core系列 35 EF保存数据(2) -- EF系列结束
一.事务 (1) 事务接着上篇继续讲完.如果使用了多种数据访问技术,来访问关系型数据库,则可能希望在这些不同技术所执行的操作之间共享事务.下面示例显示了如何在同一事务中执行 ADO.NET SqlCl ...
- asp.net core系列 34 EF保存数据(1)
一. 基本数据 每个EF上下文实例都有一个 ChangeTracker(更改跟踪器),它负责跟踪需要写入数据库的更改. 当更改实体类的实例时(修改属性,删除实例,新建实例等),这些更改会记录在 Cha ...
- asp.net core系列 33 EF查询数据 (2)
一. 原生SQL查询 接着上篇讲.通过 Entity Framework Core 可以在使用关系数据库时下降到原始 SQL 查询. 在无法使用 LINQ 表达要执行的查询时,或因使用 LINQ 查询 ...
随机推荐
- npm 安装cnpm淘宝镜像时报错解决
详细报错 D:\workspace\es61> npm install -g cnpm --registry=https://registry.npm.taobao.org npm WARN d ...
- java位移运算符 转
https://blog.csdn.net/qq_36134429/article/details/78286416#commentsedit java移位运算符不外乎就这三种:<<(左移 ...
- 如何修改SnipeIT的部分设置
作为一款开源的资产管理系统,Snipe-IT非常的好用又结实,但是原始设置对中国用户有些不方便,部分汉化没有完成,需要直接修改代码,下面把常用的修改记录如下: 1.修改资产打印标签中的文本名称 找到 ...
- 初次部署django+gunicorn+nginx
初次部署django+gunicorn+nginx 博客详细地址 https://www.cnblogs.com/nanrou/p/7026802.html 写在前面,这只是我所遇到的情况,如果有 ...
- 关于在centos7 64为引用android so引发的问题修复
背景: 公司有解码的app,解码库位c++编写so动态库. 之前做过一版在调用html5摄像头,然后提取图像进行解码,后面因为图像质量不佳放弃. 最近 因为小程序api有更新 可以获取到相对清晰的图像 ...
- h5适配的解决方案
一. 流程 设计师以750pt×1334pt尺寸进行设计(当然高度随内容变化),最后用该尺寸的设计稿进行标注.切图,前端采用淘宝的开源方案flexible进行适配. 二. flexible使用方法 F ...
- vue项目开发基本目录结构
§ 目录结构 . ├── build/ # Webpack 配置目录 ├── dist/ # build 生成的生产环境下的项目 ├── src/ # 源码目录(开发都在这里进行) │ ├── ass ...
- 你不知道的JS之 this 和对象原型(一)this 是什么
原文:你不知道的js系列 JavaScript 的 this 机制并没有那么复杂 为什么会有 this? 在如何使用 this 之前,我们要搞清楚一个问题,为什么要使用 this. 下面的代码尝试去 ...
- Java基础-对象与类
面向对象程序设计概述 面向对象的程序设计(简称OOP)时当今主流的程序设计范型,已经取代了"结构化"过程化程序设计开发技术,Java是完全面向对象的. 类 类设计构造对象的模板或蓝 ...
- python 模型 ORM简介
Django之ORM (Object Relational Mapping(ORM)一.ORM介绍1.ORM概念 对象关系映射模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.2.OR ...