02020401 EF Core基础01-EF Core简介和开发环境搭建、实体类、配置类、继承DbContex的类、Migration包的使用
1. EF Core简介(视频3-1)
-
本课程需要你有数据库、SQL等基础知识。
-
关系数据库:MySql、SQL Server、Oracle等。
- 表(字段/列),表与表之间通过外键关联。
-
对象数据库:只关心存什么,不关心怎么存。
- 如MongoDB
- 目前还是比较理论化,用的比较少。
- 之前比较激进的数据库用MongoDB,但是效果不好。
1.1 ORM简介
- ORM:Object Relational Mapping。让开发者用对象操作的形式操作关系数据库。
- ORM引擎负责将对象存储到关系型数据库里面。
- 存的是C#对象,取的也是C#对象,由ORM在C#和关系型数据库之间做双向转换。
// ORM插入伪代码
User user = new User(){Name="admin",Password="123"};
orm.Save(user);
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// ORM查询伪代码
Book b = orm.Books.Single(b=>b.Id==3||b.Name.Contains(".NET"));
string bookName = b.Name;
string aName = a.Author.Name;
1.2 有哪些ORM
- EF core、Dapper、SqlSugar、FreeSql等
1.3 EF Core与其他ORM比较
- 1、Entity Framework Core(EF Core)是微软官方的ORM框架。
- 优点:功能强大、官方支持、生产效率高、力求屏蔽底层数据库差异;
- 缺点:复杂、上手门槛高、不熟悉EFCore的话可能会进坑。
- 2、Dapper。是stackoverflow公司开发的。Dapper可以视为一个轻量级的ORM,或者说是增强版的SQLHelper。
- 优点:简单,N分钟即可上手,行为可预期性强;
- 缺点:生产效率低,需要处理底层数据库差异。
- 3、EF Core是模型驱动(Model-Driven)的开发思想,Dapper是数据库驱动(DataBase-Driven)的开发思想的。没有优劣,只有比较。
- 4、性能: Dapper等≠性能高;EF Core≠性能差。5、EF Core是官方推荐、推进的框架,尽量屏蔽底层数据库差异,.NET开发者必须熟悉,根据项目情况再决定用哪个。
1.4 ORM框架选择
- 老师的建议
- 对于后台系统、信息系统等和数据库相关开发工作量大的系统,且团队比较稳定,用EF Core;
- 对于互联网系统等数据库相关工作量不大的系统,或者团队不稳定,用Dapper。
- 在项目中EF Core和Dapper可以混用,只要注意EF Core的缓存、Tracking等问题即可。
1.5 EF Core与EF比较
- 1、EF有DB First、Model First、Code First。EF Core不支持模型优先,推荐使用代码优先,遗留系统可以使用Scaffold-DbContext来生成代码实现类似DBFirst的效果,但是推荐用Code First 。
- 2、EF会对实体上的标注做校验,EF Core追求轻量化,不校验。
- 3、熟悉EF的话,掌握EFCore会很容易,很多用法都移植过来了。EF Core又增加了很多新东西。
- 4、EF中的一些类的命名空间以及一些方法的名字在EF Core中稍有不同。
- 5、EF不再做新特性增加。
2. 搭建EF Core开发环境(视频3-2)
2.1 用什么数据库
- 1、EF Core是对于底层ADO.NET Core的封装,因此ADO.NET Core支持的数据库不一定被EF Core支持。
- 数据库要支持EF Core。这个数据库只有ADO.NET Core支持是不够的,数据库还要支持EF Core Provider。
- 2、EF Core支持所有主流的数据库,包括MS SQL Server、Oracle、MySQL、PostgreSQL、SQLite等。可以自己实现Provider支持其他数据库。国产数据库支持问题。
- Pomelo.EntityFrameworkCore.Mysql,开源的MySQL EF Provider。如果用MySQL,推荐用这个开源的。
- 3、对于SQLServer支持最完美, MySQL、PostgreSQL也不错(有能解决的小坑)。这三者是.NET圈中用的最多的三个。本课程主要用SQLServer讲,如果用其他数据库只要改一行代码+绕一些小坑即可,大部分代码用法不变。EF Core能尽量屏蔽底层数据库差异。
2.2 开发环境搭建
- 经典步骤:建实体类;建配置类;建DbContext;生成数据库;编写调用EF Core的业务代码。
// 新建实体类:Book.cs
using System;namespace EFCoreDemo
{public class Book{public long Id { get; set; } //主键,EFCore会自动将long映射为数据库中的类型public string Title { get; set; }//标题,EFCore会自动将long映射为数据库中的类型public DateTime PubTime { get; set; }//发布日期,EFCore会自动将long映射为数据库中的类型public double Price { get; set; }//单价,EFCore会自动将long映射为数据库中的类型}
}}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 新建实体类:Person.cs
namespace EFCoreDemo
{public class Person{public long Id { get; set; }public long Name { get; set; }public long Age { get; set; }}
}
2.3 安装依赖包
- 安装包:Install-Package Microsoft.EntityFrameworkCore.SqlServer
- 这个包依赖于EF Core的包,因此安装这个包的时候会自动安装EF Core包。
- 注意:Microsoft.EntityFrameworkCore.SqlServer 9.0.9 与 net5.0 (.NETCoreApp,Version=v5.0) 不兼容,这里采用5.0.4版本。
// 程序包管理器控制台:
install-package microsoft.entityframeworkcore.sqlserver -version 5.0.4
2.4 创建配置类
- 创建实现了IEntityTypeConfiguration接口的实体配置类,配置实体类和数据库表的对应关系。
// 新建与Book类相关的配置类BookEntityConfig
class BookEntityConfig : IEntityTypeConfiguration<Book> // 泛型接口,这个Book表示是与哪个实体类配置。
{public void Configure(EntityTypeBuilder<Book> builder){builder.ToTable("T_Books");}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 新建与Person类相关的配置类PersonConfig
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace EFCoreDemo
{class PersonConfig : IEntityTypeConfiguration<Person>{public void Configure(EntityTypeBuilder<Person> builder){builder.ToTable("T_Persons");}}
}说明:如果实体类不加配置类,那么任然会生成表,表名默认为实体类名+s,而不是T_实体类s的形式。
2.5 创建继承自DbContext的类
// 创建继承自DbContext的类
class TestDbContext:DbContext
{public DbSet<Book> Books { get; set; } // @1protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connStr = "Server=.;Database=CoreDataDB;Trusted_Connection=True;MultipleActiveResultSets=true";optionsBuilder.UseSqlServer(connStr); // @2}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly); // @3}
}说明:
1. 在@1.1处,泛型类型与实体类Book关联,属性用Book类的复数形式。在@1.2处泛型类型与实体类Person关联,属性用Person类的复数形式。
2. 在@2处,指定连接哪个数据库
3. 在@3处,指定配置类在哪,即BookConfig和PersonConfig这两个配置类在哪。
3.1 this表示当前程序集。
3.2 ApplyConfigurationsFromAssembly方法会加载当前程序集所有实现了IEntityTypeConfiguration<Book>接口的实现类。本例有两个,即BookConfig和PersonConfig两个配置类。
2.6 Migration数据库迁移概述
- 面向对象的ORM开发中,数据库不是程序员手动创建的,而是由Migration工具生成的。
- 关系数据库只是盛放模型数据的一个媒介而已,理想状态下,程序员不用关心数据库的操作。
- 根据对象的定义变化,自动更新数据库中的表以及表结构的操作,叫做Migration(迁移)。
- 迁移可以分为多步(项目进化),也可以回滚。
- 传统的数据库驱动的开发模式里面,数据表是程序员自己在SSMS里面创建的。
- 而在ORM框架中,数据库是由工具通过实例类来创建的,不需要程序员干预。
2.7 开发环境安装Migration包
- 为了使用生成数据库的工具,Nuget安装Microsoft.EntityFrameworkCore.Tools,否则执行Add-Migration等命令会如下报错
- 安装包:install-package microsoft.entityframeworkcore.tools -version 5.0.4

2.8 开发环境使用Migration步骤
-
在“程序包管理器控制台”中执行如下命令Add-Migration InitialCreate会自动在项目的Migrations文件夹中中生成操作数据库的C#代码。
- 新增一个表,在表里增加或者删除一个列。这里面每一次操作都是一次Migration。
- 为了区分不同的Migration,我们需要给它取不同的名字。需要再Add-Migration后添加合法的变量名称。
-
step1 查看当前项目资源管理器目录

- step2 在程序包管理器控制台执行:Add-Migration Init

// 在程序包管理器中执行与结果反馈
PM> Add-Migration Init
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM>
- step3 当前项目资源管理器目录会自动增加一个文件夹
- 注意此时通过SSMS查看数据表是没有的。

- step4 在程序包管理器控制台执行:update-database
PM> update-database
Build started...
Build succeeded.
Applying migration '20250918125952_Init'.
Done.
PM> 说明:执行update-database会编译项目,如果项目其它与数据库不相关的代码有错误,编译不通过的话,那么创建数据表也会失败。
- step5 查看SSMS中数据表

- T_Books和T_Persons表已经建好了。注意T_Configs是之前项目的表,并非此次创建的。
2.9 修改T_Persons表
- step1 修改Person类,增加或添加属性。
// 修改Person.cs类
namespace EFCoreDemo
{public class Person{public long Id { get; set; }public long Name { get; set; }public long Age { get; set; }public string BirthPlace { get; set; } // 新增属性}
}
- step2 执行Add-Migration,并带一个新名字
PM> add-migration addbirth
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM> 说明:addbirth为取的新名字。
- step3 在解决方案资源管理器会增加xxx.addbirth.cs项

-
关注数字的编号,有当前日期20250918和125952组成一个。由20250918134209组成另一个。
- 134209大于125952,因此134209表示最新。
-
step4 在程序包管理器控制台执行:update-database
PM> update-database
Build started...
Build succeeded.
Applying migration '20250918132409_addbirth'.
Done.
PM>
- step5 查看SSMS,T_Persons表新增了一行。

2.10 修改表结构
1、项目开发中,根据需要,可能会在已有实体中修改、新增、删除表、列等。
2、想要限制Title的最大长度为50,Title字段设置为“不可为空”,并且想增加一个不可为空且最大长度为20的AuthorName(作者名字)属性。
首先在Book实体类中增加一个AuthorName属性
3、修改BookEntityConfig
builder.ToTable("T_Books");
builder.Property(e => e.Title).HasMaxLength(50).IsRequired();
builder.Property(e => e.AuthorName).HasMaxLength(20).IsRequired();
4、执行Add-Migration AddAuthorName_ModifyTitle。取名字有意义
5、Update-Database
- step1 → 修改项目中相关代码
// 1. 修改Book.cs中的实体类,增加AuthorNmae属性
using System;namespace EFCoreDemo
{public class Book{public long Id { get; set; } //主键public string Title { get; set; }//标题public DateTime PubTime { get; set; }//发布日期public double Price { get; set; }// 价格public string AuthorName { get; set; } // 新建属性(对应数据表中的行)}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 2. 修改BooConfig.cs中的实体类
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EFCoreDemo
{class BookEntityConfig : IEntityTypeConfiguration<Book> // 泛型接口,这个Book表示是与哪个实体类配置。{public void Configure(EntityTypeBuilder<Book> builder){builder.ToTable("T_Books"); // T_Books表与Book实体类相对应builder.Property(e => e.Title).HasMaxLength(50).IsRequired(); // @1builder.Property(e => e.AuthorName).HasMaxLength(20).IsRequired(); // @2}}
}说明:
1. 在@1处,HashMaxLength(50)表示最大长度为50。IsRequired()表示不可为空。
2. 在@2处,也表示最大长度为50,不可为空。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
namespace EFCoreDemo
{public class Person{public long Id { get; set; }public long Name { get; set; }public int Age { get; set; } // 修改Age为int类型public string BirthPlace { get; set; } // 新增属性public double? Salary { get; set; } // 可为空的double类型}
}
- step2 → 执行add-migration和update-database
PM> add-migration v1
Build started...
Build succeeded.
An operation was scaffolded that may result in the loss of data. Please review the migration for accuracy. // @3
To undo this action, use Remove-Migration.
PM> update-database
Build started...
Build succeeded.
Applying migration '20250918134652_v1'.
Done.
PM> 说明:因为在@1处修改了Title的长度,那么可能存在数据丢失或者被截断。因此在@3处提示了警告。
- step3 → 查看SSMS

3. 总结

结尾
书籍:ASP.NET Core技术内幕与项目实战
视频:https://www.bilibili.com/video/BV1pK41137He
著:杨中科
ISBN:978-7-115-58657-5
版次:第1版
发行:人民邮电出版社
※敬请购买正版书籍,侵删请联系85863947@qq.com※
※本文章为看书或查阅资料而总结的笔记,仅供参考,如有错误请留言指正,谢谢!※