.NET 6+ 项目连接 MySQL 最稳路径是 MySqlConnector + Pomelo.EntityFrameworkCore.MySql;必须禁用 MySql.Data,否则易引发连接泄漏、迁移失败及时区错乱;连接字符串需包含 Allow User Variables=True、SslMode=Required(生产)、Convert Zero Datetime=True 等关键参数;DbContext 必须注册为 Scoped 生命周期,且版本探测建议硬编码避免权限或网络问题。

直接用 MySqlConnector 配合 EF Core 是当前 .NET 6+ 项目连接 MySQL 最稳的路径;别碰 MySql.Data,它在 EF Core 场景下容易触发连接泄漏、迁移失败、时区错乱三连击。
MySqlConnector + EF Core 的 NuGet 安装组合
EF Core 本身不自带 MySQL 驱动,必须显式引入兼容包。只装一个包是不够的:
-
Microsoft.EntityFrameworkCore(核心运行时) -
Microsoft.EntityFrameworkCore.Tools(迁移命令支持) -
Pomelo.EntityFrameworkCore.MySql(关键!这是基于MySqlConnector实现的 EF Core 官方推荐 provider)
注意:Pomelo.EntityFrameworkCore.MySql 内部已引用 MySqlConnector,无需再单独安装后者;装了 MySql.Data 反而可能引发程序集冲突,导致 InvalidOperationException: No database provider has been configured。
DbContext 配置中 connection string 的关键参数
EF Core 连接 MySQL 不只是填个地址就完事。以下参数漏掉任一,都可能在高并发或生产环境出问题:
-
Server=127.0.0.1;Port=3306;Database=mydb;Uid=root;Pwd=123456;— 基础项 -
Allow User Variables=True— 必开,否则 EF Core 的某些查询(如含变量的 GROUP BY)会报Unknown column '@p0' -
SslMode=Required(生产)或SslMode=None(本地开发)— MySQL 8.0+ 默认强制 SSL,不设会卡在握手阶段 -
Connection Timeout=15;Default Command Timeout=60;— 避免迁移或长查询无响应挂死 -
Convert Zero Datetime=True;Allow User Variables=True;— 处理datetime字段存 '0000-00-00' 的老表
示例完整字符串:"Server=127.0.0.1;Port=3306;Database=testdb;Uid=appuser;Pwd=sec123;SslMode=Required;Allow User Variables=True;Convert Zero Datetime=True;"
注册 DbContext 时别写错 ServiceLifetime
在 Program.cs 中注册 DbContext,常见错误是把生命周期写成 AddSingleton 或裸 new 实例:
- ❌
services.AddSingleton<myappcontext>()</myappcontext>— 多线程共享单例 DbContext,必然报InvalidOperationException: A second operation started on this context before a previous operation completed - ✅ 正确写法:
services.AddDbContext<myappcontext>(options => options.UseMySql(connStr, ServerVersion.AutoDetect(connStr), ...))</myappcontext>
EF Core 默认注册为 Scoped,符合 Web 请求生命周期;若手动指定,必须用 AddScoped,不能降级为 Transient(性能差)或升级为 Singleton(线程不安全)。
迁移命令执行前必须确认 MySQL 版本探测逻辑
Pomelo.EntityFrameworkCore.MySql 依赖 ServerVersion.AutoDetect(connStr) 推断 MySQL 版本,用于生成兼容 SQL。但这个探测会真实连一次库 —— 如果连接字符串权限不足(比如只有 SELECT),就会报 Access denied for user ... to database 'information_schema'。
解决办法有两个:
- 临时提权:让数据库用户拥有
SELECT权限访问information_schema(开发环境可接受) - 硬编码版本(推荐):
new ServerVersion(new Version(8, 0, 33), ServerType.MySql),避免探测,也杜绝因网络波动导致迁移失败
特别注意:MySQL 8.0 和 5.7 对 JSON、窗口函数、CTE 的语法支持差异极大,版本写错会导致 dotnet ef migrations add 生成非法 SQL。
真正容易被忽略的是时区处理 —— MySQL 默认用系统时区,DateTime 字段从 C# 写入后查出来变成 UTC 或偏移错乱,不是连接字符串没加 TimeZone=UTC,而是 EF Core 模型里忘了给属性加 [Column(TypeName = "datetime")] 或 HasConversion 显式约定。这点不调通,上线后订单时间全乱。


















