EF Core 源码构建完全指南:从环境准备、本地 SDK 安装到本地 NuGet 包打包
【免费下载链接】efcoreEF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.项目地址: https://gitcode.com/GitHub_Trending/ef/efcore
本文基于 EF Core 仓库中的 getting-and-building-the-code.md 编写,系统讲解如何从零开始拉取、构建并测试 EF Core 源码:涵盖 SQL Server 与 Cosmos 测试前置环境、仓库自带的build/restore/test脚本族、global.json驱动的本地 .NET SDK 安装机制、build -pack本地 NuGet 包构建,以及 Visual Studio 集成与常见构建错误的排查方法。读完后你可以独立完成 EF Core main 分支的编译、测试和本地包分发验证。
适用范围:仅面向 main 分支
文档开宗明义:以下所有步骤仅适用于当前main 分支。EF Core 的构建体系会随版本迭代变化(例如 .NET SDK 版本、Arcade 工具链版本),如果你的工作基于某个 release 分支,请以该分支中的同名文档为准。
环境前置条件
EF Core 本身编译不需要额外安装任何前置组件(构建脚本会自行下载所需的 .NET SDK)。但运行测试时需要本地具备特定数据库:
SQL Server 测试:LocalDb 或独立 SQL Server
SQL Server 相关的功能测试要求本机有一个可用的 SQL Server 实例,可选方案:
- SQL Server LocalDb:通常随安装 Visual Studio(选择 "ASP.NET and web development" 工作负载)一并获得,开箱即用;
- SQL Server Express 或 Developer Edition:可运行在 Windows 或 Linux 上。注意:当不使用 LocalDb 时,必须设置环境变量
Test__SqlServer__DefaultConnection,其值为测试应使用的连接字符串,否则测试无法定位数据库。
Cosmos 测试:Azure Cosmos 模拟器(可选)
- 需要安装Azure Cosmos 模拟器并使用默认安装选项;每次重启机器后都要手动启动模拟器。
- 该部分是可选的:如果模拟器不可用,Cosmos 测试会自动跳过。如果你不打算修改 Cosmos 相关代码,完全可以不装模拟器,交给 CI 系统去跑。
- 实用技巧:在模拟器中关闭 "Rate Limiting"(限流),可以让 Cosmos 测试跑得更快——模拟限流会显著拖慢测试节奏,具体开关位置见上面的截图。
.NET SDK:非必需但强烈建议
虽然构建脚本在需要时会自行下载 SDK,但文档仍建议本机安装最新公共预览版 .NET SDK。这与仓库 global.json 的内容一致:
{ "sdk": { "version": "11.0.100-rc.1.26420.103", "allowPrerelease": true, "rollForward": "latestMajor", "paths": [".dotnet", "$host$"], "errorMessage": "The required .NET SDK wasn't found. Please run ./restore.sh or .\\restore.cmd to install it." }, "test": { "runner": "Microsoft.Testing.Platform" }, "msbuild-sdks": { "Microsoft.DotNet.Arcade.Sdk": "11.0.0-beta.26456.102" } }从这份配置可以看出几个关键机制:
paths: [".dotnet", "$host$"]表示优先查找仓库根目录下的.dotnet文件夹(即构建脚本安装的本地 SDK),找不到再回落到系统全局安装的 SDK;errorMessage字段明确提示:找不到 SDK 时请运行./restore.sh或restore.cmd安装——这正是build作为"重要一步"的原因;msbuild-sdks锁定了 Arcade 工具链(Microsoft.DotNet.Arcade.Sdk)版本,保证 MSBuild 行为与 dotnet 官方仓库一致;test.runner声明测试通过Microsoft.Testing.Platform运行。
Fork 与 Clone
如果你的目的是向 EF Core 贡献代码,先在 GitHub 上创建 fork,再用你习惯的 git 客户端克隆仓库。克隆主仓库:
git clone https://github.com/dotnet/efcore.git若已在个人账号下 fork 出名为efcore的仓库,则克隆自己的 fork:
git clone https://github.com/myusername/efcore.git构建:build 脚本为什么是"重要一步"
构建代码只需在仓库根目录执行:
build文档特别强调这是重要步骤(important step),因为它会在 EF Core 仓库旁边安装一份预览版 .NET SDK,确保 EF Core 始终使用预期的 SDK 与 MSBuild 版本进行编译。执行build同时完成还原包(restore)和构建全部项目,但不运行测试。
根目录脚本的真实调用链
文档给出的参数表中提到的根目录build、restore.cmd、test.cmd等文件都是"薄封装"。从源码看,它们的实现极其简洁:
- restore.cmd 的全部内容就是调用
eng\common\build.ps1 -nodeReuse:$false -restore; - restore.sh、test.sh 同理,分别调用 eng/common/build.sh 并附带
--restore、--test参数(同时传--nodeReuse false以避免复用 MSBuild 节点)。
也就是说,所有入口最终都汇聚到eng/common/build.ps1与eng/common/build.sh这对核心脚本,它们把命令行开关翻译成 MSBuild 属性(/p:Restore=…、/p:Build=…、/p:Test=…、/p:Pack=…等)再驱动构建。
常用构建参数
完整参数列表可通过build -h查看。文档列出的常用动作与对应脚本如下:
| Build argument | Action | Script file |
|---|---|---|
-restore | Restore packages(还原 NuGet 包) | restore.cmd |
-build | Build all projects(构建所有项目) | build.cmd |
-test | Run all tests, requires build(运行全部测试,需先构建) | test.cmd |
-pack | Build and produce NuGet packages(构建并产出 NuGet 包) | None(无对应根目录脚本) |
进一步阅读 eng/common/build.sh 中的usage()帮助文本,可以看到更多本地开发会用得到的参数:
| 参数 | 作用 |
|---|---|
--rebuild | 重新构建(rebuild) |
--clean | 清理artifacts目录 |
--integrationTest/--performanceTest | 运行集成测试 / 性能测试 |
--sourceBuild/--productBuild | 源构建 / 模拟 .NET 完整产品(VMR)构建方式,会连带触发 restore、build、pack |
--configuration <value> | 构建配置:Debug(本地默认)或Release |
--verbosity <value> | MSBuild 详细度:quiet / minimal / normal / detailed / diagnostic |
--binaryLog | 生成 MSBuild 二进制日志,方便用 MSBuild 日志查看器分析 |
--projects <value> | 指定要构建的项目或解决方案文件,而不是全仓库 |
未在上面列出的命令行参数会直接透传给 MSBuild(脚本源码中有properties+=("$1")的兜底分支),例如后文的/p:OfficialBuildId=…。
构建本地 NuGet 包:OfficialBuildId 与本地包源
build -pack会把所有 EF Core NuGet 包构建到artifacts\packages目录。但这里有一个坑:无论构建多少次,包的版本号都不变,这会与 NuGet 的包缓存机制"打架"——缓存可能让你拿到的还是旧包。因此文档要求每次打包时指定新的内部构建号:
build /p:OfficialBuildId=20231212.6 -pack构建号遵循 .NET 内部约定yyyyMMdd.x(日期 + 递增序号),每构建一批就把 "x" 加一。
要消费这些本地包,需要在你的解决方案或项目目录放置NuGet.config,把本地包目录加入包源。文档给出的完整示例:
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" /> <add key="Local" value="C:\local\code\efcore\artifacts\packages\Debug\Shipping" /> </packageSources> </configuration>注意Local源指向的是artifacts\packages\Debug\Shipping——即Debug配置下的 Shipping(正式发行)包目录;若你用 Release 配置打包,路径相应调整。
顺带一提,EF Core 仓库自身的 NuGet.config 也值得看一眼:它通过<clear />清空继承源后,显式添加了dotnet-eng、dotnet-tools、dotnet8至dotnet12等一系列 Azure DevOps 公共 feed。这也正是后文排查构建错误时"检查包源 URL 是否可达"的对象——本地网络若访问不了这些 feed,restore 阶段就会失败。
在 Visual Studio 中使用源码
务必先执行一次命令行build,再打开解决方案。原因是构建脚本安装的是仓库本地的预览 SDK,而 IDE 默认走系统 SDK,两者版本不一致会引发奇怪的构建失败。
startvs.cmd 做了什么
文档推荐的入口命令:
startvs.cmd EFCore.sln从 startvs.cmd 的源码可以确认它完成三件事:
- 设置
DOTNET_ROOT指向仓库根目录下的.dotnet\(若定义了DOTNET_GLOBAL_INSTALL_DIR则优先使用),保证 .NET 使用仓库本地安装的dotnet.exe; - 把该目录插到 PATH 最前面,让 Visual Studio 找到正确的 SDK;
- 若本地
dotnet.exe尚不存在,先自动调用restore.cmd补装;最后用start打开你传入的解决方案。
文档还提醒了两点:
startvs实际打开的是系统默认关联.sln的程序。如果你装了多个 IDE 或多个版本的 Visual Studio,请确认默认关联正确,或直接编辑脚本写死目标程序;- 如果你安装了最新的公共预览版 .NET SDK,理论上可以跳过
startvs直接打开解决方案。但 EF Core 可能依赖比最新预览版更新的内部变更,直接打开出现意外错误时,请回到startvs方案,并确保 Visual Studio 也是最新预览版。
Linux/macOS 下可以查看 activate.sh 做类似配置:它export DOTNET_ROOT="$DIR/.dotnet"、把本地 dotnet 加入 PATH 头部,并定义deactivate函数用于还原环境。
运行测试
EF Core 的测试使用xUnit.net编写,绝大多数测试运行器都能跑。命令行方式(需要先完成 build):
testtest脚本(test.cmd/ test.sh)本质是带--test参数调用eng/common/build.ps1/eng/common/build.sh。结合前文前置条件,请留意:
- SQL Server 测试依赖 LocalDb 或已配置
Test__SqlServer__DefaultConnection的独立实例; - Cosmos 测试在模拟器不可用时会被跳过。
常见构建错误的排查步骤
文档给出的三步排查法,建议按顺序执行:
- 检查包源可达性:确认根目录 NuGet.config 中列出的包源 URL(如
dotnet-eng、dotnet11等 feed)都能访问; - 清理源码目录:
git clean -xid可清除 EF 源码目录中的未跟踪文件; - 清理 NuGet 缓存:
nuget.exe locals all -clear会清空所有 NuGet 缓存(nuget.exe也可用dotnet nuget替代操作)。
这三步分别对应"网络/源问题"、"脏工作区问题"、"缓存污染问题"三类最常见的构建失败根因。
小结:关键文件速查
| 环节 | 关键文件 |
|---|---|
| 本文主体 | docs/getting-and-building-the-code.md |
| SDK/工具链锁定 | global.json |
| 包源配置 | NuGet.config |
| 根入口脚本 | build.cmd、restore.cmd、test.cmd 及对应.sh |
| 核心构建实现 | eng/common/build.sh、eng/common/build.ps1 |
| IDE 环境注入 | startvs.cmd、activate.sh |
| Cosmos 限流开关截图 | docs/rate_limiting.png |
掌握"前置条件 →build(装本地 SDK + restore + build)→test/build -pack→startvs打开 IDE"这条主线,再配合global.json、NuGet.config和eng/common下的脚本源码,你就能在本地完整复现 EF Core 的构建与测试流程。
【免费下载链接】efcoreEF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.项目地址: https://gitcode.com/GitHub_Trending/ef/efcore
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考