简介:MySQL Connector/Net 6.8.3 noinstall 版是面向 .NET 开发者的官方数据库驱动包,适用于使用 C#、VB.NET 连接 MySQL 的桌面与 Web 项目。该版本免安装、解压即用,便于在受限环境或 CI 流程中快速部署,适合需要手动管理依赖的中高级开发者。压缩包共 21 个文件,约 3.45MB,以 13 个 dll 运行时组件为主,另含 3 个 html 第三方许可说明、chm 帮助文档、readme、changes、copying 及 Release Notes.txt,按 v2.0、v4.0、v4.5 等目标框架分目录组织,方便按项目版本取用。已有 278 人学习下载。包内文档覆盖安装配置、版本变更、许可证条款与 API 参考,可帮助读者快速完成驱动引用、排查兼容性问题,并了解各 .NET 框架版本对应的组件差异。
1. 为什么我还在用 mysql-connector-net-6.8.3-noinstall:一个被低估的稳定版本
如果你维护过 .NET Framework 4.0/4.5 的老项目,大概率遇到过这种场景:服务器不能联网,NuGet 还原失败,而项目里偏偏要用 MySQL。这时候mysql-connector-net-6.8.3-noinstall.zip就是那个能救命的包。它本质上是 MySQL 官方提供的 .NET 连接器,免安装、解压即用,核心程序集是MySql.Data.dll,直接引用就能连库。6.8.3 这个版本号看着老,但它对 .NET Framework 2.0 到 4.5 的兼容性极稳,不像 8.x 那样强依赖新运行时,也不像某些中间版本在ConnectionString解析上出玄学问题。适合谁?维护遗留系统的、做内网部署的、需要把连接器随程序一起打包分发的。下面我从解压到跑通查询,把每一步拆开讲。
2. 解压后先别急着引用:目录结构与程序集选型
2.1 压缩包里到底有什么
把mysql-connector-net-6.8.3-noinstall.zip解压后,你会看到几个关键目录。很多人直接双击MySql.Data.dll就引用,结果运行时提示Could not load file or assembly,就是因为没看清版本对应关系。
| 目录/文件 | 用途 | 目标框架 |
|---|---|---|
v4.0/MySql.Data.dll | 主连接器程序集 | .NET Framework 4.0+ |
v4.5/MySql.Data.dll | 主连接器程序集 | .NET Framework 4.5+ |
v2.0/MySql.Data.dll | 旧版兼容 | .NET Framework 2.0/3.5 |
MySql.Web.dll | Web 提供程序(成员资格、角色) | 按目录区分 |
MySql.Data.Entity.dll | Entity Framework 支持 | 按目录区分 |
installer/ | 安装脚本,noinstall 版用不到 | — |
选型逻辑很简单:你的项目目标框架是什么,就选对应目录。如果项目是 .NET Framework 4.5.2,优先用v4.5下的 DLL;如果只是 4.0,用v4.0。别混用,混用会在运行时抛FileLoadException。
2.2 引用方式:拷贝到 lib 还是直接引用
我一般会把对应版本的MySql.Data.dll拷贝到解决方案下的lib/文件夹,然后在项目里「添加引用」指向这个本地路径。这样做的好处是:源码包自带连接器,换台机器编译不用重新找包。
# 假设解压到了 D:\tools\mysql-connector-net-6.8.3-noinstall # 在解决方案根目录建 lib 文件夹,把 v4.5 的 DLL 拷进去 mkdir lib copy "D:\tools\mysql-connector-net-6.8.3-noinstall\v4.5\MySql.Data.dll" lib\逻辑说明:copy命令把目标框架对应的程序集复制到项目可控的目录。参数上,路径里的v4.5要按你实际项目框架替换。拷贝后,在 Visual Studio 里右键「引用」→「添加引用」→「浏览」→ 选中lib\MySql.Data.dll。注意不要勾选「复制本地」为 False,否则发布时会缺 DLL。
2.3 验证程序集是否加载成功
引用完先别写业务代码,用一段最小代码验证连接器能不能被 CLR 加载。
using System; using MySql.Data.MySqlClient; class Program { static void Main() { // 只打印连接器版本,不实际连库 var asm = typeof(MySqlConnection).Assembly; Console.WriteLine("Loaded: " + asm.FullName); Console.WriteLine("Location: " + asm.Location); } }逻辑说明:typeof(MySqlConnection).Assembly拿到当前加载的程序集实例,FullName会显示版本号,正常应包含Version=6.8.3.0。如果这里就报错,说明引用路径不对或框架不匹配,不用往下走。参数上无需配置,纯验证。
3. 连接字符串与核心参数:把坑挡在第一次查询之前
3.1 一个能跑通的最小连接串
6.8.3 的MySqlConnection对连接串格式比较宽容,但有几个参数必须显式给,否则会踩默认值的坑。
using System; using MySql.Data.MySqlClient; class Program { static void Main() { string connStr = "Server=127.0.0.1;Port=3306;Database=testdb;" + "Uid=root;Pwd=yourpassword;Charset=utf8;" + "SslMode=None;AllowUserVariables=True;"; using (var conn = new MySqlConnection(connStr)) { try { conn.Open(); Console.WriteLine("State: " + conn.State); Console.WriteLine("ServerVersion: " + conn.ServerVersion); } catch (MySqlException ex) { Console.WriteLine("Error " + ex.Number + ": " + ex.Message); } } } }逻辑说明:conn.Open()触发实际连接,ServerVersion返回 MySQL 服务端版本,能打印出来说明握手成功。参数逐个说:SslMode=None在内网环境避免证书协商失败;AllowUserVariables=True允许 SQL 里用@var用户变量,很多老项目依赖这个;Charset=utf8防止中文乱码。Port默认 3306,改了要同步。
3.2 连接池参数怎么设才不炸
6.8.3 默认开启连接池,Pooling=true。如果不限制Max Pool Size,高并发下会把 MySQL 的max_connections吃满,报Too many connections。
string connStr = "Server=127.0.0.1;Database=testdb;Uid=root;Pwd=yourpassword;" + "Pooling=true;Min Pool Size=5;Max Pool Size=50;" + "Connection Lifetime=300;Connection Timeout=10;";逻辑说明:Min Pool Size=5保持 5 个常驻连接,减少频繁建连开销;Max Pool Size=50是单进程上限,要小于 MySQL 服务端max_connections除以应用实例数;Connection Lifetime=300让连接最多活 300 秒,避免长时间空闲被防火墙断掉;Connection Timeout=10是建连超时秒数,内网可以设 5。这些值没有绝对标准,按你实际 QPS 调,但Max Pool Size一定要设。
3.3 参数化查询:别用字符串拼接
老项目里常见"SELECT * FROM users WHERE name='" + name + "'",这在 6.8.3 下照样能跑,但 SQL 注入风险极高。正确做法是用MySqlParameter。
string sql = "SELECT id, name FROM users WHERE name = @name AND status = @status"; using (var cmd = new MySqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@name", "张三"); cmd.Parameters.AddWithValue("@status", 1); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { Console.WriteLine(reader.GetInt32("id") + " - " + reader.GetString("name")); } } }逻辑说明:AddWithValue会自动推断类型,但要注意@status传 int 时别传字符串,否则 MySQL 会做隐式转换导致索引失效。reader.GetInt32("id")按列名取值,比按序号可读。参数名前的@不能省,6.8.3 对命名参数大小写不敏感,但建议保持一致。
4. 避坑与排查:6.8.3 最常见的五类翻车现场
4.1 现象:报「Authentication method 'caching_sha2_password' not supported」
原因:MySQL 8.0 默认认证插件是caching_sha2_password,而 6.8.3 只支持mysql_native_password。解决:要么改用户认证插件,要么换连接器版本。改法:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpassword'; FLUSH PRIVILEGES;注意:这会影响该用户所有连接,生产环境改前确认没有其他新客户端依赖新插件。
4.2 现象:中文写入变成问号
原因:连接串没指定Charset,或数据库/表字符集不是 utf8。解决:连接串加Charset=utf8,并检查表定义SHOW CREATE TABLE users;确认DEFAULT CHARSET=utf8。如果服务端是 utf8mb4,连接串写Charset=utf8mb4,6.8.3 支持这个值。
4.3 现象:ExecuteReader后连接状态变Closed
原因:用了CommandBehavior.CloseConnection且 reader 被释放。解决:要么别用这个行为,要么确保 reader 释放前处理完数据。我一般不用它,手动using控制连接生命周期更清晰。
4.4 现象:发布到 IIS 后报「Unable to find the requested .Net Framework Data Provider」
原因:MySql.Data.dll没被复制到输出目录,或web.config里DbProviderFactories没注册。解决:确认 DLL 的「复制本地」为 True;在web.config的system.data节加:
<system.data> <DbProviderFactories> <remove invariant="MySql.Data.MySqlClient" /> <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.8.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" /> </DbProviderFactories> </system.data>注意PublicKeyToken必须是c5687fc88969c44d,写错会加载失败。
4.5 现象:Timeout expired但数据库没慢查询
原因:连接池耗尽,新请求在等空闲连接。解决:抓SHOW PROCESSLIST看连接数,调大Max Pool Size,同时检查代码里是否有连接没释放。最常见的是MySqlConnection没放using里,异常时泄漏。
5. 进阶技巧:把 6.8.3 塞进现代构建流程
5.1 用 NuGet 本地源管理这个包
虽然 noinstall 是解压包,但你可以把它做成离线 NuGet 包,方便团队统一版本。步骤:建一个文件夹local-nuget,把MySql.Data.dll按 NuGet 包结构放好,用nuget pack生成.nupkg,然后在 VS 里添加本地源。
# 目录结构:MySql.Data.6.8.3/lib/net45/MySql.Data.dll nuget pack MySql.Data.nuspec -OutputDirectory local-nuget逻辑说明:nuspec里指定id、version、dependencies。这样 CI 构建时不用手动拷 DLL,nuget restore自动拉。参数上-OutputDirectory指定输出目录,团队共享这个目录即可。
5.2 验证连接器是否真的在工作
别只看Open()成功,跑一个带参数、带事务的完整链路。
using (var conn = new MySqlConnection(connStr)) { conn.Open(); using (var tran = conn.BeginTransaction()) { using (var cmd = new MySqlCommand("INSERT INTO logs(msg) VALUES(@m)", conn, tran)) { cmd.Parameters.AddWithValue("@m", "test"); cmd.ExecuteNonQuery(); } tran.Rollback(); // 回滚,不污染数据 } Console.WriteLine("Transaction test passed."); }逻辑说明:BeginTransaction后命令要带上tran,否则不在同一事务。Rollback验证事务控制正常。如果这里报MySqlException,看错误号,1213是死锁,1205是锁等待超时,跟连接器本身无关。
5.3 一个我踩过的坑:AllowZeroDateTime
MySQL 的0000-00-00日期在 6.8.3 默认会抛异常。如果老数据里有这种值,连接串加AllowZeroDateTime=True,读取时用MySqlDateTime类型接。我当年不知道这个参数,排查了一下午,血泪经验。从那以后我每次接老库都先SELECT一遍日期列看有没有零值,再决定要不要开这个开关。希望帮到你。
本文还有配套的精品资源,点击获取