关键在于区分ef6与efcore:ef6依赖.edmx和设计器,仅支持.net framework项目,需安装ef6 tools;efcore无设计器、代码生成模型,仅支持.net 5+,须选带“.net x.x”后缀模板,并单独安装microsoft.entityframeworkcore.tools包。

Visual Studio 中用 Entity Framework 开发 C# 项目,关键不在“能不能用”,而在于你选的是 EF Core 还是 EF6,以及项目类型是否匹配——不匹配会导致 DbContext 编译失败、设计器打不开、甚至 NuGet 包装不上。
EF Core 和 EF6 在 Visual Studio 里根本不是一回事
EF6 依赖 .edmx 文件和可视化设计器,只支持 .NET Framework 项目(比如“Windows 窗体应用 (.NET Framework)”),且必须安装“Entity Framework 6 Tools”组件;EF Core 没有设计器,靠代码生成模型,只支持 .NET 5+(包括 .NET 6/7/8/9),对应项目模板是“Windows 窗体 App”或“WPF App”(带“.NET x.x”后缀)。混用会直接报错:The type or namespace name 'DbContext' could not be found,哪怕你已装了包。
- 新建项目时,如果目标是 EF Core,必须选带“.NET x.x”后缀的模板,不能选带“(.NET Framework)”字样的
- EF6 的
ADO.NET 实体数据模型项模板在 .NET Core/5+ 项目中根本不会出现 - Visual Studio 安装器里,“.NET 桌面开发”工作负荷默认只装 EF6 工具;EF Core 需要额外确保勾选了“ASP.NET 和 Web 开发”或手动安装
Microsoft.EntityFrameworkCore.Tools
安装 EF Core 包时最常漏掉的一步
只装 Microsoft.EntityFrameworkCore.SqlServer 或 Pomelo.EntityFrameworkCore.MySql 是不够的——Microsoft.EntityFrameworkCore.Tools 必须单独安装,否则 dotnet ef 命令不可用,Scaffold-DbContext 命令在包管理器控制台里会提示“找不到该命令”。
- 用 CLI:运行
dotnet add package Microsoft.EntityFrameworkCore.Tools(注意不是dotnet tool install) - 用 NuGet 包管理器:在“工具 → NuGet 包管理器 → 管理解决方案的 NuGet 包”中,切换到“包含预发行版”,搜索并安装
Microsoft.EntityFrameworkCore.Tools到**启动项目**(不是类库项目) - 如果项目是 Windows 窗体应用,还需确认
Startup.cs或Program.cs中没有残留的 ASP.NET Core 服务注册逻辑,否则DbContext构造函数注入会失败
DbContext 配置写在 OnConfiguring 里容易出问题
把连接字符串硬编码在 OnConfiguring 方法里看似简单,但实际部署时几乎必然要改——本地 SQLite 测试、开发环境 SQL Server、生产环境 MySQL,连接方式完全不同。硬编码会导致每次换环境都要改代码、重新编译。
- 推荐做法:把连接字符串放
appsettings.json(WinForms 需手动加载)或ConfigurationManager.AppSettings(.NET Framework) - WinForms 项目没内置
IConfiguration,得自己用JsonSerializer.Deserialize<dictionary string>></dictionary>加载 JSON 文件,或直接读取Application.ExecutablePath + ".config" - 如果用了依赖注入(如 WinForms 中手动构建
ServiceProvider),DbContext必须注册为Scoped,不能是Singleton,否则并发查询会抛A second operation started on this context before a previous operation completed
Code First 迁移在桌面应用里不能自动执行
dotnet ef migrations add Init 和 dotnet ef database update 只在开发阶段有用;发布成单文件或 ClickOnce 后,这些命令无法运行,迁移也不会自动触发——EF Core 不会在启动时悄悄建库或跑迁移。
- 桌面应用必须显式调用
context.Database.Migrate()(同步)或await context.Database.MigrateAsync()(异步),一般放在窗体Load事件或主程序入口 - SQLite 场景下,
Database.EnsureCreated()更轻量,但不支持增量迁移;一旦模型变更,它会删库重建,慎用于已有数据的场景 - 如果用
EnsureCreated(),记得检查context.Database.GetPendingMigrationsAsync()是否为空,避免误删用户数据
真正麻烦的从来不是“怎么加包”或“怎么写 DbContext”,而是跨环境配置传递、迁移时机控制、以及 WinForms 主线程阻塞导致的数据库操作卡 UI——这些点不提前想清楚,上线后查起来比重写还费劲。










