02020405 EF Core基础05-EF Core反向工程、EF Core和ADO.NET Core的联系、EF Core无法做到的事情
1. 数据库设计的三种形式(视频3-9)
- DB First → 先在数据库中将数据表建好了,然后再反向生成实体类。
- 简单,但是不适合开发复杂项目。
- Model First → 先创建一个类似于图形化模型的东西,再根据图形化来生成实体类和数据库。
- Code First → 先手写实体类,然后根据实体类在数据库中生成数据表。
- EF Core只支持这种。
1.1 反向工程介绍
- 方向工程:根据数据库表来反向生成实体类
- 在新项目里面,不推荐反向工程创建数据库。
- 在已经有数据库的项目里面,可以使用。
Scaffold-DbContext 'Server=.;Database=MyDB;Trusted_Connection=True;MultipleActiveResultSets=true' Microsoft.EntityFrameworkCore.SqlServer说明:Scaffold → 脚手架
1.2 先通过SSMS创建一个数据库
- step1 → 删除现有数据库:CoreDataDb → 删除 → 删除对象面板 → 勾选:关闭现有连接(避免因为连接问题导致无法删除数据库)

- step2 → 创先一个新数据库:数据库 → 新建数据库 → 数据库名称:MyDB → 确定

- step3 → 创建数据表:MyDB → 表 → 新建 → 表 → 添加相关信息 → 确定

1.3 通过.NET Core控制台项目实现反向工程
- step1 → 项目名称AutoCreateDB,并且添加EF Core相关的依赖包,如下演示直接复制.csproj文件部分来添加依赖包
// AutoCreateDB.csproj
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net5.0</TargetFramework></PropertyGroup></Project>
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// AutoCreateDB.csproj直接添加依赖包
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net5.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include="microsoft.entityframeworkcore.sqlserver" Version="5.0.4" /><PackageReference Include="microsoft.entityframeworkcore.tools" Version="5.0.4"><PrivateAssets>all</PrivateAssets><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets></PackageReference></ItemGroup></Project>说明:
1. 在csproj里面直接添加,就不需要通过install-package microsoft.enti...这样安装依赖包了。
2. 此时AutoCreateDB项目只有一个Program.cs文件。
- step2 → 在程序包管理器控制台输入如下代码。
- 注意,设定当前项目AutoCreateDB为默认启动项,同时包管理器默认项目也为当前项目AutoCreateDB。
PM> Scaffold-DbContext 'Server=.;Database=MyDB;Trusted_Connection=True;MultipleActiveResultSets=true' Microsoft.EntityFrameworkCore.SqlServer
Build started...
Build succeeded.
To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
PM>
- step3 → 解决方案资源管理器会自动生成对应的数据表和配置文件。

- 反向生成的相关文件代码如下
// TPerson
using System;
using System.Collections.Generic;#nullable disablenamespace AutoCreateDB
{public partial class TPerson{public long Id { get; set; }public string Name { get; set; }public DateTime? BirthDay { get; set; }}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;#nullable disablenamespace AutoCreateDB
{public partial class MyDBContext : DbContext{public MyDBContext(){}public MyDBContext(DbContextOptions<MyDBContext> options): base(options){}public virtual DbSet<TPerson> TPersons { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){if (!optionsBuilder.IsConfigured){
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.optionsBuilder.UseSqlServer("Server=.;Database=MyDB;Trusted_Connection=True;MultipleActiveResultSets=true");}}protected override void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.HasAnnotation("Relational:Collation", "Chinese_PRC_CI_AS");modelBuilder.Entity<TPerson>(entity =>{entity.ToTable("T_Persons");entity.Property(e => e.Name).HasMaxLength(50);});OnModelCreatingPartial(modelBuilder);}partial void OnModelCreatingPartial(ModelBuilder modelBuilder);}
}说明:如果有多张表,操作流程一样,会自动生成多个实体类。
1.4 使用Force flag来生成表
- 当已经通过反向工程生成了表,此时SSMS又手动增加了表,操作如下。
PM> Scaffold-DbContext 'Server=.;Database=MyDB;Trusted_Connection=True;MultipleActiveResultSets=true' Microsoft.EntityFrameworkCore.SqlServer
Build started...
Build succeeded.
To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
The following file(s) already exist in directory 'E:\0201\EFCoreDemo\AutoCreateDB\': MyDBContext.cs,TPerson.cs. Use the Force flag to overwrite these files.
PM> 说明:直接使用Scaffold-DbContext 'Server=.;Database=MyDB;Trusted_Connection=True;MultipleActiveResultSets=true' 这个命令会报错。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
PM> Scaffold-DbContext 'Server=.;Database=MyDB;Trusted_Connection=True;MultipleActiveResultSets=true' Microsoft.EntityFrameworkCore.SqlServer -Force
Build started...
Build succeeded.
To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
PM> 说明:此时可以再次增加SSMS中新增加的表对应的实体类。注意这样会丢失之前操作的数据,慎用反向工具。
1.5 反向工程注意事项
1、生成的实体类可能不能满足项目的要求,可能需要手工修改或者增加配置。
2、再次运行反向工程工具,对文件所做的任何更改都将丢失。
3、不建议把反向工具当成了日常开发工具使用,不建议DBFirst。
- DB First一开始很爽,后面会让你慢慢想哭。Code First,YYDS。
2. EF Core底层如何操作数据库(视频3-10)
2.1 EF Core底层原理
- 很多人说EF Core很烂,实际上是你不会用。不要轻易说EF Core不好。
- 著名的程序员杨中科说过:框架是帮助程序员简化工作的,不是让程序员变成傻瓜的。
2.2 ADO.NET Core简介

- 传统项目 → 应用程序直接和ADO.NET Core交互,ADO.NET Core把SQL命令扔给数据库去执行。
- ADO.NET Core:把SQL指令扔给数据库执行的开发包。
2.3 EF Core底层是有ADO.NET Core存在的

- 应用程序与ADO.NET Core之间多了EF Core。
- 通过EF Core,那么应用程序就不用写SQL语句了,而是C#代码。由EF Core负责将C#代码生成SQL语句。
- ADO.NET Core将EF Core生成的SQL语句扔给数据库执行。
- EF Core底层任然是依靠ADO.NET Core把命令扔给数据库去执行。
- EF Core和ADO.NET Core没有区别可言,它们两个根本不是一个层面的东西。
- EF Core不是用来替代ADO.NET Core的
- EF Core是基于ADO.NET Core的,EF Core的底层是基于ADO.NET的。
- 其它的ORM框架,如Dapper、FreeSql等也和EF Core一样,将C#代码转换为SQL语句,然后交给ADO.NET Core。
2.4 EF Core到数据库的流程

- EF Core和ADO.NET Core不是相互替代的关系,而是相互协作的关系。
2.5 查看EF Core生成的SQL语句
1、SQL Server Profiler查看SQLServer数据库当前执行的SQL语句。
2、var books = ctx.Books.Where(b => b.Price > 10 || b.Title.Contains("张"));
- 在04020202中的7小结中有介绍SQL Server Profiler的用法。
2.6 EF Core总结
- EF Core把C#代码转换为SQL语句的框架
3. EF Core有哪些做不到的事情(视频3-11)
3.1 EF Core无法支持的情况示例
- C#千变万化;SQL功能简单。存在合法的C#语句无法被翻译为SQL语句的情况。
// 示例1:无法实现
var books = ctx.Books.Where(b => IsOK(b.Title));
private static bool IsOK(string s) // IsOK是自定义方法
{return s.Contains("张");
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 示例2:无法实现
var books = ctx.Books.Where(b =>b.Title.PadLeft(5)=="hello");
3.2 EF Core不同数据库的不同

var persons = ctx.TPersons.Where(p => p.Name.ToLower()=="杨中科"); // 在SQL Server中支持,在MySql中不支持。
- AST → 抽象语法树(了解即可)。
- C#代码有EF Core的核心翻译为AST。
- 各种类型的数据库的EF Core Provider将AST翻译为各种数据库的SQL语句,再将SQL语句扔给各种数据库的ADO.NET Provider。
结尾
书籍:ASP.NET Core技术内幕与项目实战
视频:https://www.bilibili.com/video/BV1pK41137He
著:杨中科
ISBN:978-7-115-58657-5
版次:第1版
发行:人民邮电出版社
※敬请购买正版书籍,侵删请联系85863947@qq.com※
※本文章为看书或查阅资料而总结的笔记,仅供参考,如有错误请留言指正,谢谢!※