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 查询 ...
随机推荐
- 20175305张天钰《java程序设计》第五周学习总结
<java程序设计>第五周学习总结 接口与实现 知识小点: (1)用Arrays.sort方法对所有实现Comparable接口的对象进行排序 (2)接口体现了has-a关系,继承体现了i ...
- 浅谈构建前端自动化工作流程一 之 node
一.Node环境 1.什么是Node? Node.js类似于jquery.js,不是js文件,也不是一个js框架,而是Server side JavaScript runTime,服务端的一个JS运行 ...
- 通过javap终极理解++i和i++的区别
一直在学习Java,碰到了很多问题,碰到了很多关于i++和++i的难题,以及最经典的String str = "abc" 共创建了几个对象的疑难杂症. 知道有一日知道了java的反 ...
- BFC特性下多栏自适应布局
BFC 已经是一个耳听熟闻的词语了,网上有许多关于 BFC 的文章,介绍了如何触发 BFC 以及 BFC 的一些用处(如清浮动,防止 margin 重叠等).虽然我知道如何利用 BFC 解决这些问题, ...
- angular1.3 video
video标签动态获取播放链接是出现 Error: $interpolate:interr Interpolation Error Error: $sce:insecurl Processing of ...
- [C++一本通-图论算法] 例4-4 最小花费
题目描述 在n个人中,某些人的银行账号之间可以互相转账.这些人之间转账的手续费各不相同.给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问A最少需要多少钱使得转账后B收到100元. 输入输 ...
- 10-Python入门学习-函数的对象与嵌套、名称空间与作用域、闭包函数
一.函数的对象 函数是第一类对象,指的是函数名指向的值(函数)可以被当作数据去使用 def func():# func=函数的内地址 print('from func') print(func) ag ...
- SpringMVC+Mybatis+MySQL8遇到的问题
搭建SpringMVC+Mybatis+MySQL8过程中遇到的坑. 1.数据库驱动要使用新版本,我的和mysql保持一致. 查看mysql版本:MySQL\bin>mysql -V 配置对应版 ...
- ES6新增的常用数组方法(forEach,map,filter,every,some)
ES6新增的常用数组方法 let arr = [1, 2, 3, 2, 1]; 一 forEach => 遍历数组 arr.forEach((v, i) => { console.log( ...
- ubuntu系统下手动安装autoconf安装包
首先简单介绍一下autoconf.Autoconf是一个可以适应多种unix类系统的shell脚本的工具. 我在往虚拟机中安装应用时,需要用到该工具,于是想下载一个.但是由于系统内核版本低,已不能用a ...