0.EF Core 源码探索-模块全景与学习路线
一、EF Core 是什么
EF Core(Entity Framework Core)是 .NET 官方的 对象关系映射器(ORM),让你用 C# 对象来操作数据库,而不必手写 SQL。
EF Core 的意义在于,把数据库操作提升到 类型安全的 C# 表达式 层面——模型就是数据库表,LINQ 就是查询语句,编译器替你检查拼写错误。
除此之外,EF Core 还提供了 Migration(迁移) 机制,让你用代码追踪数据库结构变更、一键升级或回滚;提供了 变更追踪(Change Tracking) 机制,让你只需修改对象属性,调用 SaveChanges() 时它自动算出要执行哪些 INSERT / UPDATE / DELETE。
同时EF Core结合DDD领域驱动设计能提供极致的编程体验。试想下当我们对模型的任意修改后,框架会自己识别出要新增、修改、还是删除、修改时是全字段覆盖还是只改某个属性。这一切都得益于EF的上下文追踪机制,我们无需在仓储上浪费精力。
二、项目整体模块拆分
EF Core 的源码在 src/ 目录下,共有约 20 个项目,按职责可以清晰地归为以下几层。
2.1 核心层
| 项目 | 作用 |
|---|---|
EFCore |
整个框架的核心主体。DbContext、DbSet、ModelBuilder、变更追踪、查询引擎抽象、值生成等所有基础能力都在这里。 |
EFCore.Abstractions |
极简的抽象层,定义了少量公共接口和特性(如 [Owned]、[Keyless]),供外部代码引用,不依赖核心层。 |
2.2 目前支持到的数据库类型
| 项目 | 说明 |
|---|---|
EFCore.Relational |
为所有关系型数据库提供公共基础:SQL 生成、表/列映射元数据、事务、存储过程支持、关系型 Migration 框架等。 |
EFCore.SqlServer |
SQL Server / Azure SQL 专属实现,翻译 LINQ 为 T-SQL,处理 SQL Server 独有特性(如 HierarchyId、JSON 列)。 |
EFCore.SqlServer.Abstractions |
SQL Server 专属的少量公共接口,供模型配置代码引用。 |
EFCore.Sqlite |
SQLite 专属实现(基于 Microsoft.Data.Sqlite)。 |
EFCore.Sqlite.Core |
SQLite 核心逻辑,EFCore.Sqlite 是它的封装入口。 |
EFCore.Sqlite.NTS |
SQLite 的 NetTopologySuite 空间数据扩展。 |
EFCore.SqlServer.NTS |
SQL Server 的 NetTopologySuite 空间数据扩展。 |
EFCore.SqlServer.HierarchyId |
SQL Server HierarchyId 类型支持。 |
EFCore.Cosmos |
Azure Cosmos DB(NoSQL)的 EF Core Provider,把 LINQ 翻译为 Cosmos SQL API 查询。 |
EFCore.InMemory |
内存数据库 Provider,主要用于单元测试,不会真正连接任何数据库。 |
2.3 工具与设计时层
| 项目 | 职责简述 |
|---|---|
EFCore.Design |
设计时工具的核心逻辑,包括 Migration 代码生成、脚手架(即从数据库逆向生成模型代码)、DbContext 工厂发现等。 |
EFCore.Tools |
dotnet-ef 工具包(NuGet)的入口,负责将 CLI 命令路由到 EFCore.Design。 |
dotnet-ef |
dotnet ef 命令行工具的主程序入口。 |
EFCore.Analyzers |
Roslyn 静态分析器,在编写代码时给出警告(如检测到可能的客户端评估问题)。 |
EFCore.Tasks |
MSBuild 任务,支持编译期代码生成(如 Compiled Models)。 |
EFCore.Templates |
dotnet new 模板,用于快速生成 EF Core 相关脚手架代码。 |
2.4 数据访问底层
| 项目 | 职责简述 |
|---|---|
Microsoft.Data.Sqlite |
SQLite 的 ADO.NET 驱动(DbConnection / DbCommand / DbDataReader 实现),EF Core 的 SQLite Provider 构建在它之上。 |
Microsoft.Data.Sqlite.Core |
Microsoft.Data.Sqlite 的核心实现,不含 Native 库绑定。 |
三、模块依赖关系
EFCore.Abstractions (最底层抽象)
└── EFCore (核心层)
├── EFCore.Cosmos (NoSQL Provider,直接依赖 EFCore)
├── EFCore.InMemory (内存 Provider,直接依赖 EFCore)
└── EFCore.Relational (关系型数据库公共层)
├── EFCore.SqlServer (SQL Server Provider)
├── EFCore.Sqlite.Core (SQLite Provider 核心实现)
│ └── Microsoft.Data.Sqlite.Core (底层 ADO.NET 驱动核心)
└── EFCore.Design (Migration 根据 model 生成数据库变更,Scaffold 根据数据库反向生成 model)
└── EFCore.Tools / dotnet-ef (命令行工具入口)
理解这张依赖图,是读源码不迷路的基础。凡是数据库无关的通用逻辑,都在 EFCore;凡是 SQL 语法相关的,都在 EFCore.Relational;具体数据库的方言翻译,在各自的 Provider 里。
四、学习路线建议
按以下顺序阅读,循序渐进,每一篇都建立在前一篇的基础上:
| 篇序 | 主题 | 对应源码项目 |
|---|---|---|
| 第 0 篇 | 模块全景与学习路线 | — |
| 第 1 篇 | 模型构建(Metadata) — EF Core 如何把你的 C# 类映射成一张"内存里的数据库设计图" | EFCore/Metadata/ |
| 第 2 篇 | DbContext 生命周期 — DbContext 的创建、配置、注入与销毁全流程 | EFCore/DbContext.cs、Infrastructure/ |
| 第 3 篇 | 变更追踪(Change Tracking) — 你改了对象属性,EF Core 怎么知道要执行 UPDATE | EFCore/ChangeTracking/ |
| 第 4 篇 | 查询管线(Query Pipeline) — LINQ 如何一步步被翻译成 SQL 并执行 | EFCore/Query/、EFCore.Relational/Query/ |
| 第 5 篇 | SaveChanges 与更新管线 — INSERT / UPDATE / DELETE 是如何被组装和执行的 | EFCore/Update/、EFCore.Relational/Update/ |
| 第 6 篇 | Migration(迁移) — 代码如何追踪数据库结构变更并生成升级脚本 | EFCore.Relational/Migrations/、EFCore.Design/Migrations/ |
| 第 7 篇 | Provider 机制 — 如何为一种新数据库写一个 EF Core Provider | EFCore.Relational/、EFCore.Cosmos/ |
| 第 8 篇 | 值生成与并发控制 — 主键生成策略、乐观并发、行版本号 | EFCore/ValueGeneration/ |
建议:先通读第 1 篇(Metadata),因为 EF Core 的一切功能都建立在"模型元数据"这一核心概念上。不理解
IModel/IEntityType/IProperty,读查询和变更追踪的代码会非常吃力。
五、快速找到入口
如果你想直接跑起来,最快的方式是:
git clone https://github.com/dotnet/efcore.git
cd efcore
用 Visual Studio 或 Rider 打开 EFCore.slnx(完整解决方案),测试项目在 test/ 目录下,里面有大量集成测试和单元测试,是理解各模块行为的绝佳参考。
最值得优先阅读的几个文件:
src/EFCore/DbContext.cs— 整个框架的门面,所有操作的起点src/EFCore/ModelBuilder.cs— 模型构建 Fluent API 的入口src/EFCore/ChangeTracking/ChangeTracker.cs— 变更追踪的对外接口src/EFCore/Query/QueryCompilationContext.cs— 查询编译的上下文,是理解查询管线的关键类

浙公网安备 33010602011771号