跟我一起学.NetCore之EF Core 实战入门,一看就会

4,140 阅读9分钟

前言

还记得当初学习数据库操作时,用ADO.NET一步一步地进行数据操作及查询,对于查询到的数据还得对其进行解析,然后封装返回给应用层;遇到这种重复而繁琐的工作,总有一些大神或团队对其进行封装,从而出现了很多ORM框架,让小伙伴把更多精力放在业务处理上,同时更多的面向程序对象开发,对工作效率的提升有很大的帮助。

目前关于C#出现了很多ORM框架,比较流行的大概有FreeSql (国内)、SqlSugar (国内)、Dapper (国外)、EF/EF Core (国外)、linq2db (国外)等,

当然也有一些小伙伴对其进行性能比较,各有优势吧。从我个人及周围的小伙伴使用来看,EF/EF Core和Dapper使用率相对比较高。这里就先说说EF Core,后续逮住机会再和小伙伴一起分享其他;

正文

随着.NetCore的迅速推进,EF Core也紧跟其步伐。目前长期支持版本是EF Core3.1,而下一个稳定版本EF Core5.0将计划随.Net5一起发布,预计应该会在这个月(2020年11月),可见微软对EF Core是非常重视的;

对于之前用过EF的小伙伴,应该都知道,EF有三种开发模式:CodeFirst、ModelFirst、DbFirst,这三种根据业务需求及个人偏好用的相对比较多的是DbFirst和CodeFirst;现在EF Core推荐使用CodeFirst的方式进行项目开发,当然也可以通过反向工程的方式,以数据库设计为先。这里都会针对这两种方式进行举例演示;

image-20201109121929839

在项目中使用CodeFirst方式,这里用的数据库是VS自带的LocalDb,项目还是老规矩,一个WebApi项目;既然实战入门,肯定得有点样子才对,所以这里就简单模仿了三层架构的形式进行举例演示,如下项目结构:

img

项目依赖如下:

  • EFCoreTestDemo API项目依赖EFCoreTestModel和EFCoreTestService项目;
  • EFCoreTestService 服务层项目依赖EFCoreTestModel和EFCoreTestRespository项目;
  • EFCoreTestRespository 数据层依赖EFCoreTestModel项目

结构好了,现在开始敲代码,比如模拟用户维护的增删改查吧; 既然是CodeFirst,先暂时把数据库放一边。 如下步骤开始:

  1. 做用户维护,肯定得有用户实体,先在Model层中增加一个用户类;

    img

  2. 接下来就要对数据进行操作,就是所谓的增删改查,既然用到EF,肯定得有一个DbContext,这个和数据存储有关,所以将其放在数据层;

    img

  3. 其实到这一步,我比较喜欢先迁移一下,看看是否有问题,能否正常生成数据库和对应的表;(其实这里可以不用急着迁移,继续编码的,但提前把问题扼杀在摇篮中是很不错的想法);

    既然要迁移,肯定得把数据的连接字符串传过去,这里是从WebApi项目的Startup中注册服务时进行传递,并指定迁移程序为WebApi项目:

    img

    上图中数据库连接字符串从何而来的,自己写的吗?哈哈哈,拷贝过来的,这里顺便把之前创建的数据库都删了,方便测试,如下图:

    img

    迁移方式有两种,一种是命令行的形式,另一种是在VS中的包管理器控制台(PMC)进行;

    **命令行方式:**需要安装命令行工具,这里使用全局安装方式,如下命令:dotnet tool install --global dotnet-ef

    在指定的迁移程序集中安装Microsoft.EntityFrameworkCore.Design,否则迁移不成功。迁移过程如下图:

    img

    **包管理器控制台(PMC)方式进行迁移:**需要在指定的迁移程序集中安装Microsoft.EntityFrameworkCore.Tools包,否则迁移失败:

    img

  4. 迁移没问题,继续回到代码逻辑;现在应该开始编辑业务代码,即对用户的增删改查,先从数据层开始吧,具体步骤见下图编号:

    img

    业务层:

    img

    控制器:

    img

    使用自带依赖注入:

    img

  5. 剩下的就是运行看结果啦,这里没有继承Swagger,使用Postman工具进行测试,如下图:

    img

通过以上步骤,使用EF Core的CodeFirst 从创建实体->迁移->最后业务编写的流程基本就是这样啦;后续如果新增实体,还是重复以上步骤。说完流程,接着说说上面过程中其他技术点↓↓↓

增删改查操作

增加用户案例,首先将原有对象进行包装,然后通过标识包装对象的状态,最后通过SaveChanges进行统一执行操作,如下:

img

用户的删除、更新与新增时同样的道理,如下:

img

查询,一般通过DbContext自带方法、Lamda表达式,或是Linq语句,同样查出可追踪的包装对象,但是可以将其查询设置为不可追踪,有时候为了提高性能,会针对进行设置或整体设置:

img

整体设置不追踪:

img

迁移命令

上面说到的迁移命令只有新增迁移和更新数据库,还有一些常用的指令也比较常用,如下:

img

通常,生成环境下一般都会采用脚本的方式生成数据库和表,那开发的时候是通过命令进行的,如何生成对应的脚本呢? 如下图:

img

对于删除迁移的场景,一般会是对当前迁移不满意,比如字段写错了、类型误用等情况,如下:

img

如上图,新增迁移已经完成了,但是由于Age使用的类型不对,要废弃这次迁移,重新进行迁移,当然也不可以不删除,但对后续查询历史迁移记录的时候会产生误解。如下删除最近一次迁移,如下:

img

表问题

在上面迁移的过程中,并没有指定表明和字段及设置对应的列类型,是EF Core框架按照默认规则,自动帮我们生成了,是不是很贴心,但是既然是默认,框架肯定不知道我们到底需要什么,如下生成的表:

img

如上图所示,EF Core框架默认将类名作为表明,生成的字符串长度都默认为最大,这些肯定不是我们想要的,所以作者肯定想到这,给我们提供了修改的方法,我们通常会采用注解的方式或是FluentApi的形式进行约束和更改,注解直接在对应列上标注,但一般会推荐使用FluentApi,相对比较灵活;在DbContext中的OnModelCreating中编写对应代码即可,如下:

img

然后重新迁移并更新到数据库,如下:

img

Linq查询

EF使用的过程中,Linq应该是少不了的,估计有小伙伴会说,直接用DbContext中提供的方法和Lamda表达式就行啦,是,那肯定是可以的,只能说还没用到精髓,哈哈哈,面向代码编程的SQL查询语句,用起来是很方便的,如下:

img

是不是看起来像SQL,虽然说是Linq新语法,但看着不陌生,用着也很方便;这里不打算深入说,只是给小伙伴们提上一嘴;那么无情吗?当然不,我把之前收集到的Linq文档已经上传,小伙伴们可以参考一下:

官方文档:docs.microsoft.com/zh-cn/dotne…

收集文档:

链接:pan.baidu.com/s/1BZivBXG9…

提取码:9qyu

img

反向工程(先有数据库设计,然后根据数据库生成对应Model)

对于一些项目,当小伙伴们接到手时候已经把数据库设计好了,这种情况没必要犟着一个一个实体敲,重新生成数据库,完全可以通过数据库反向生成代码,反正怎么方便就怎么来;还有一种情况就是很多小伙伴还是比较喜欢数据库优先的开发模式,直接反向工程就好啦;

这里用之前创建的数据和User表,然后建了一个test项目,里面只安装了EF Core的核心包和Design包,如下:

img

同样使用命令行或包管理控制台都行,这里就使用命令行,在test项目目录下执行以下命令(这里是SqlServer,还需要安装Microsoft.EntityFrameworkCore.SqlServer包):

dotnet ef dbcontext scaffold "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=EFCoreTest1;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" "Microsoft.EntityFrameworkCore.SqlServer" -o ./Models --context EFCoreTestContext  --context-dir ./ -f

以上命令简单说明:

dotnet ef dbcontext scaffold后面指定数据库连接字符串;

第二个参数代表是对应数据库指定的Provider,及对应数据库对应的Nuget包;

-o:代表是生成的实体类存放的位置;

--context:生成的dbContext的类名称;

--context-dir:指定生成的dbContext存放的位置;

-f:覆盖现有文件;

-v:显示迁移过程及报错信息;

-t:指定表反向生成代码,如果不指定代表所有表都生成;

-n:指定生成类名的命名空间,这个EF Core5.0提供;

—context-namespace:指定生成DbContext的命名空间,这个EF Core5.0提供;

注:生成的类和DbContext可以根据参数最终生成到对应位置,满足自己需求。

如果是MySql,需要安装Pomelo.EntityFrameworkCore.MySql包,其他步骤都一样,这里就不演示了,就留给小伙伴练习吧;真的不要嫌简单,只有亲手做了,遇到问题,然后解决,最终才能提升,亲身体会。

总结

这里只是简单说说EF Core的使用,迁移流程及反向工程操作分享,其他的进阶使用会陆续分享,小伙伴们也可以自己去加强,我这里有的资源,都会进行分享;说到这,后续文件下载地址大家只能在公众号聊我啦,前两篇由于博文带文件下载地址,有些博客平台把我禁言了,很是尴尬,不过修改申诉过啦。

博文源代码github地址:github.com/zyq025/DotN…

一个被程序搞丑的帅小伙,关注"Code综艺圈",识别关注跟我一起学~~~

撸文不易,莫要白瞟,三连走起~~~~