简介:MySQL Connector/Net 6.8.3 免安装版是 MySQL 官方面向 .NET 开发人员推出的数据库驱动程序,能帮助使用 C#、VB.NET 等语言的开发者顺畅连接 MySQL 服务器。该版本无需安装,解压即可部署,便于在多套环境中快速迁移与离线集成。压缩包共 21 个文件,大小仅 3.45MB,主体为 13 个动态链接库文件,覆盖 .NET 2.0、4.0、4.5 及 Entity Framework 5/6 等不同目标框架;另附编译后的 CHM 帮助手册、开源许可证页面与使用说明文档。通过这些文档,开发者可以查看版本变更记录、了解手动配置步骤、查阅接口用法并确认授权条款,从而安全高效地将数据库操作集成到项目中。目前已有 280 人学习下载,适合需要快速获取官方驱动并适配多种 .NET 版本的项目开发人员。
1. mysql-connector-net-6.8.3-noinstall.zip 是给谁的:没有管理员权限也能把 MySQL 驱动装进项目的 zip 包
mysql-connector-net-6.8.3-noinstall.zip 这名字老,但解决的恰恰是最现实的问题:生产服务器在隔离网络里,没有外网也没有管理员权限,还要给老项目补一个 MySQL 驱动。noinstall 是官方给的免安装分发形态,不跑 MSI、不碰 GAC 和 machine.config,解压出 dll 直接引用就能用。这篇不聊新功能,只把这个 zip 包讲透:哪个 dll 干什么、怎么引用跑通第一条查询、什么时候才需要手工注册全局、5 个高频坑怎么绕。适合正在维护 .NET Framework 4.x + EF 5/6 老项目的人,也适合做离线交付物、被安装包权限卡住的工程师。读完你手里的 zip 就不只是临时救急的压缩包,而是可以固化成团队部署基座的东西。
2. 拆开 noinstall 包先分清 dll:MySql.Data 和 EF 程序集谁管什么事
拿到这个 zip 的第一反应是解压,第二反应通常是懵:根目录散着四五个 dll,还有 docs 和 samples,到底引用哪个?这一章先把包里的家底摸清楚,再教你怎么用 PowerShell 自检 dll 的真实身份。这一步做扎实了,后面注册配置才不会抄错版本号。
2.1 解压后的结构与四个关键程序集:docs、samples 与真正要引用的文件
noinstall 包的典型布局是 docs 目录(帮助文档)、samples 目录(示例代码),加上根目录几个 dll 和一份许可文本。不同构建的目录组织略有差异,但核心程序集就那么几个,关键是把它们各自的职责记住。
| 程序集 | 职责 | 什么时候引用 |
|---|---|---|
| MySql.Data.dll | ADO.NET 驱动核心,连接、命令、DataReader 全在这里 | 所有场景必引 |
| MySql.Data.Entity.dll | EF 4/5 的集成层 | 老项目用 EF5 时引 |
| MySql.Data.EntityFramework.dll | EF 6 的集成层,6.8 起单独提供 | 用 EF6 时引 |
| MySql.Web.dll | ASP.NET 的 Membership / Role provider | WebForms 老项目才需要 |
先说几条实战经验。第一,MySql.Data.dll 是全家桶,其余全是围绕它的扩展层,只跑原生 ADO.NET 的话引用一个文件就够。第二,EF 那俩文件在部分构建里只有 MySql.Data.Entity.dll 一个名字,也可能同时存在两个,动手前先看解压目录,别背文件名,后面配置 provider 时文件名直接决定 type 字符串对不对。第三,MySql.VisualStudio.dll 是给 Visual Studio 设计器用的,部署和编译都不需要,别复制进 bin 目录,省得惹出版本冲突。
我习惯把整个 zip 解压到项目的 vendor 目录而不是扔桌面,目录名就叫 mysql-connector-net-6.8.3,docs 和 samples 一起留着。理由很简单:版本管理里能看出这个项目锁定了哪版驱动,换版本只改目录不碰代码。docs 目录里的 HTML 帮助在断网排查时是救命的东西,连接串参数的默认值、枚举值都在里面写着,比在网上搜二手答案靠谱。
2.2 用 PowerShell 读程序集元数据:版本、强名称与目标框架一次看清
noinstall 场景最忌讳抄配置。网上贴的 machine.config 片段里 PublicKeyToken 往往来自另一个版本,抄过来就是一次翻车。正确做法是拿你手上这份 dll 实测,PowerShell 几行命令就能把注册配置需要的三个信息全读出来。
# 只读元数据,不会触发依赖程序集加载,安全 $dll = (Resolve-Path ".\MySql.Data.dll").Path $an = [System.Reflection.AssemblyName]::GetAssemblyName($dll) $an | Format-List Name, Version, FullName # PublicKeyToken 是 byte 数组,转成小写十六进制字符串才和配置里写法一致 $tokenHex = ($an.GetPublicKeyToken() | ForEach-Object { $_.ToString("x2") }) -join "" "PublicKeyToken=$tokenHex" # 目标运行时版本:v4.0.30319 表示 .NET Framework 4.x $asm = [System.Reflection.Assembly]::ReflectionOnlyLoadFrom($dll) $asm.ImageRuntimeVersion这里要解释两个关键点。第一,GetAssemblyName只读清单不加载程序集,所以即使目录里缺依赖文件也不会报错,适合拿来核对交付物。第二,GetPublicKeyToken的输出一定要转成小写十六进制,否则后面填进 machine.config 的 type 字符串会格式对不上。6.8.3 这类官方构建的 token 通常是个固定值,但如果 dll 被人重新编译过、或者从私有构建流出来的,token 就会变。所以判断标准只有一个:以你 dll 的实测输出为准,网上任何人贴的 token 都只能当参考。
还有一个隐藏坑:FullName里的 Version 才是 CLR 解析时用的版本号,不是你在文件属性里看到的"文件版本"。两者在个别构建里会不一致,配置里永远填FullName里的那个版本号。
2.3 6.8.3 的兼容边界:.NET Framework 4.0、EF5/EF6 与新版驱动的取舍
6.8.3 诞生在 .NET Framework 4.0/4.5 时代,这个定位决定了很多事不能拿今天的新驱动标准去要求它。它没有完整的 async/await 支持,异步走的是 BeginExecuteReader 那套老模式;它对 MySQL 8.0 的 caching_sha2_password 认证也不认(第 5 章细说);但反过来,如果你的项目锁定在 Framework 4.x,它的表现非常稳定,配置简单,资料也多。
选型上有几条边界值得记下来。第一,纯 ADO.NET + .NET Framework 4.x,6.8.3 完全够用,不用为"新版更好"去冒险升级。第二,EF5 项目用 MySql.Data.Entity.dll;EF6 项目用 MySql.Data.EntityFramework.dll,并且大概率要处理 DbConfiguration 的注册(第 4 章给方案)。第三,项目如果是 .NET Core / .NET 5+,不要碰 6.8.3,直接换支持异步的新版驱动,硬套只会得到一堆连接池和 SSL 层的怪问题。
| 你的项目现状 | 建议做法 |
|---|---|
| .NET Framework 4.0,原生 ADO.NET | 放心用 6.8.3,只需 MySql.Data.dll |
| .NET Framework 4.5,EF5 | 用 6.8.3 + MySql.Data.Entity.dll |
| .NET Framework 4.5,EF6 | 用 6.8.3 + MySql.Data.EntityFramework.dll,注意 DbConfiguration |
| .NET Core / .NET 5+ | 放弃 6.8.3,换新版驱动 |
| 服务器是 MySQL 8.0+ | 6.8.3 能连,但账号认证必须兼容旧协议 |
决定守住 6.8.3 的团队,通常不是贪便宜,而是交付基线不允许动。换新版驱动看着只是换 dll,实际上 SslMode 默认值变了、连接池行为变了、异常类型变了,都是要重新过测试的。所以我的态度是:没有明确收益就不升,锁版本本身就是一种工程决策。
3. 最小可运行方案:引用 MySql.Data.dll 跑通第一条 SELECT
这一章直接给能抄的作业:把 dll 放进项目、写连接串、跑查询。读完这一章,你不需要任何注册表操作就能在开发机跑通,这也是 noinstall 包相比 MSI 最舒服的地方。
3.1 复制 dll 到项目并添加引用:HintPath 与 Copy Local 的配合
常见做法是把 dll 放在项目根目录的 lib 文件夹里,用 csproj 的 HintPath 引用,而不是直接从解压目录拖到引用列表里。为什么?HintPath 是相对路径,换机器、换分支都能解析;直接从解压目录引用,路径一旦失效,编译报错都看不清是缺文件还是路径变了。
<ItemGroup> <Reference Include="MySql.Data"> <HintPath>..\..\vendor\mysql-connector-net-6.8.3\MySql.Data.dll</HintPath> <Private>True</Private> </Reference> </ItemGroup>这段配置里,HintPath是 csproj 文件到 dll 的相对路径,..\..\vendor是向上两级找到 vendor 目录。Private等价于 Visual Studio 属性面板里的"复制本地",设为 True 表示编译后把 MySql.Data.dll 复制到 bin 输出目录。这两个参数要配套:HintPath 保证编译时找到程序集,Private 保证运行时 bin 目录里有程序集。只配 HintPath 不配 Private,开发机能跑,部署到干净机器就报找不到 dll,这是最常见的第一道坑。
3.2 连接串参数拆解:Server、Port、SslMode、CharSet 等 10 个高频项
连接串是 MySQL 驱动里最像玄学的地方,因为驱动对未知参数是静默忽略的。你把参数名拼错一个字母,它不报错,只是默默用默认值,最后表现为"连不上"或者"连上了但字符集不对"。所以与其背参数,不如先把高频参数的默认值和影响背下来。
| 参数 | 默认值 | 说明 |
|---|---|---|
| Server | localhost | 主机地址,生产环境尽量写内网 IP |
| Port | 3306 | 非默认端口必须显式写 |
| Database | 无 | 相当于 USE db |
| Uid / Pwd | 无 | 账号密码 |
| SslMode | Preferred | 6.8 的默认值,很多连接问题的源头 |
| CharSet | utf8 | 老库可能是 latin1,要按实际库核对 |
| ConnectionTimeout | 15 | 单位秒,指建立连接的超时 |
| Pooling | True | 连接池开关 |
| MaximumPoolSize | 100 | 池上限,高并发要评估 |
| AllowUserVariables | False | 允许 SQL 里用 @ 用户变量 |
SslMode 值得单独拎出来说。6.8.3 的默认值是 Preferred,意味着服务器支持 SSL 就会尝试握手,而老版本 MySQL 自签证书、或者协议协商有问题时,这个握手会直接失败。开发环境连不上的时候,第一个动作就是把 SslMode 显式写成 None,排除掉 SSL 协商这个变量。CharSet 则是另一个重灾区:数据库表是 latin1,连接串写 utf8,查询结果不乱,但写入就变成乱码;反过来更麻烦。原则是连接串字符集对齐数据库实际编码,而不是对齐"你以为的编码"。
3.3 一个能直接抄的查询示例:参数化查询与显式类型
下面这段是完整的控制台查询代码,把 dll 引用好、连接串一换就能跑。注意 6.8.3 是 Framework 4.0 时代的 API,代码里我用的是老式 using 块写法,别拿 C# 8 的using var去套,编译过不去。
using System; using MySql.Data.MySqlClient; class Program { static void Main() { // SslMode=None 先排除 SSL 握手干扰,CharSet 对齐库编码 string connStr = "Server=127.0.0.1;Port=3306;Database=appdb;Uid=appuser;Pwd=yourpass;SslMode=None;CharSet=utf8;ConnectionTimeout=15;Pooling=true;MaximumPoolSize=50;AllowUserVariables=true"; using (var conn = new MySqlConnection(connStr)) { conn.Open(); // 参数名用 @ 前缀,和 SQL 占位符一一对应 using (var cmd = new MySqlCommand("SELECT id, name, created_at FROM users WHERE status = @status", conn)) { // 数字参数建议显式声明 DbType,见下方说明 cmd.Parameters.Add("@status", MySqlDbType.Int32).Value = 1; using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { Console.WriteLine("{0}\t{1}", reader.GetInt32(0), reader.GetString(1)); } } } } } }代码逻辑不复杂:Open 建立连接,MySqlCommand 承载 SQL,参数通过 Parameters 集合传入,ExecuteReader 返回流式读取的数据集。值得讲的是参数化的两个细节。第一,必须用命名参数@status,驱动会把参数值和 SQL 分开发送,既防注入又避免字符串拼接的引号地狱。第二,我在注释里特意不用AddWithValue,而是用Add加MySqlDbType.Int32显式指定类型。这是 6.x 时代的血泪经验:AddWithValue在部分版本里会把数字参数推断成字符串,导致 WHERE 条件走不上索引,表大了直接慢查询。数字参数显式声明类型,字符串参数再看情况,这个习惯值得固定下来。
跑通这段代码后,你的 noinstall 之旅就完成了一半。接下来要考虑的是:这个驱动要不要给整台机器共享?要不要接 EF?这就进入第 4 章的全局注册路线。
4. noinstall 的正式部署路线:GAC、machine.config 与 EF 的 provider 注册
项目内引用只解决"我的进程能用"。真实部署里还有两类诉求:IIS 上多个站点共用一份驱动,或者老工具通过 DbProviderFactories 按 invariant name 找工厂类。这时候就得手工做 MSI 安装包本来会做的事:装 GAC、注册 machine.config、配 EF provider。这一章按三步走。
4.1 为什么 noinstall 还要手动注册:IIS 站点共享驱动的真实需求
先纠正一个常见误解:把 dll 放到 bin 目录,CLR 就会优先加载它而忽略 GAC。实际 CLR 对强名称程序集的解析顺序是:先查 GAC,再查应用目录。如果机器上装过 MSI 版本的连接器,GAC 里已经有一份同版本或者更高版本的 MySql.Data,你 bin 目录里那份反而可能不被使用,或者两个版本在同一进程里纠缠。这个机制决定了两种场景必须走注册路线。
第一种场景是 IIS 多站点。每个站点的 bin 各放一份 6.8.3 dll 不是不行,但维护成本高,升级驱动要全站挨个替换。把驱动装进 GAC,所有站点共享同一份,配合 machine.config 里的 DbProviderFactories 注册,站点的 web.config 只需要写连接串。第二种场景是依赖工厂模式的老工具,它们不直接 new MySqlConnection,而是通过DbProviderFactories.GetFactory("MySql.Data.MySqlClient")拿工厂,这条路必须要 machine.config 或 app.config 里注册过才能走通。
我的原则是:单机单应用就用 bin 引用,别折腾 GAC;多站点、多应用、有老工具依赖工厂模式的,才上全局注册。全局注册不是免费的,它把版本冲突从单个应用级升级成了机器级,一改全动,必须谨慎。
4.2 用 gacutil 安装并检查程序集:命令与常见参数
GAC 的安装工具是 gacutil,它在 Windows SDK 的 Tools 目录里,具体位置因 SDK 版本而异,通常在NETFX 4.x Tools子目录下。没有 SDK 的机器可以用开始菜单搜 gacutil 碰碰运气。整个安装要点只有三个:管理员权限、用 dll 绝对路径、安装后立刻验证。
gacutil /i "C:\app\vendor\mysql-connector-net-6.8.3\MySql.Data.dll" # 验证:/l 是列出,可以用通配符 gacutil /l MySql.Data # 卸载指定版本:避免误删同名的其他版本 gacutil /u MySql.Data,Version=6.8.3.0命令本身很好懂,/i是 install,/l是 list,/u是 uninstall。注意/u后面如果不带 Version 限定,会把所有版本的 MySql.Data 全部卸载,所以在多版本共存的机器上做任何卸载操作前,先/l MySql.Data看清现状。gacutil /if是强制覆盖,一般不建议用,它会在程序集被占用时仍然覆盖,容易让运行中的站点下一次加载就崩。
还有一点:GAC 只解决"程序集在全局可用",不解决"DbProviderFactories 认识它"。这两件事是分开的,很多人把 dll 塞进 GAC 就以为万事大吉,结果工厂模式还是报"provider 未注册",那是因为第 4.3 节的配置没做。
4.3 注册 DbProviderFactories:machine.config 与 app.config 两条路径怎么选
注册工厂类有两条路径:改机器级 machine.config,或者改应用级 app.config / web.config。选择标准一句话:只影响当前应用就写 app.config,整机所有应用都要用就写 machine.config。注意 machine.config 在 64 位系统上有两份,32 位进程读Framework目录那份,64 位进程读Framework64目录那份,IIS 应用池的位数决定读哪份,九个字:先看池子位数再改文件。
<configuration> <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> </configuration>这段配置里的关键是type字符串,它由四段组成:类型全名、程序集名、版本号、公钥令牌。MySql.Data.MySqlClient.MySqlClientFactory是工厂类全名,MySql.Data是程序集名,Version 和 PublicKeyToken 必须和 2.2 节 PowerShell 实测的一致。我这里写的 token 是常见值,如果你的 dll 实测不一致,全文替换即可。remove节点写在add前面是防冲突的惯用手法:如果机器配置里已经注册过同名 invariant,remove先清掉再add,避免"已存在"的报错。
4.4 注册后的验证:用 DbProviderFactories 反向核对版本
配置写没写对,光看文本没用,要运行时验证。PowerShell 一行命令就能确认工厂能不能按 invariant 名字拿到,以及拿到的版本是不是 6.8.3.0。
$f = [System.Data.Common.DbProviderFactories]::GetFactory("MySql.Data.MySqlClient") $f.GetType().Assembly.FullName如果输出里包含Version=6.8.3.0,说明你机器上那个进程该读的配置文件生效了。如果输出是别的版本,说明你改的文件不是这个进程实际读取的那份,去核对 x86/x64 的 machine.config 路径。如果抛异常说 provider 未注册,先查remove和add的 invariant 拼写是否完全一致,invariant 是大小写不敏感的,但字符不能差。这一步验证是 EF 场景的前置条件,第 5 章第一个坑就跟它直接相关。
5. noinstall 避坑手册:五个高频故障从现象到解决
用 noinstall 包最磨人的不是安装,而是排障。这一章写五个我反复遇到的故障,全部按"现象 → 原因 → 解决"的顺序展开。每一个背后都对应一类配置错误,看完能省掉大半天的排查时间。
5.1 现象:运行时抛 "Could not load file or assembly 'MySql.Data, Version=6.8.3.0'"
编译通过,一运行就抛 FileLoadException 或 FileNotFoundException,报错里指名要 6.8.3.0 版本。这个现象在部署到新机器时尤其常见。原因是强名称程序集的解析要求版本完全匹配,CLR 会先按完整名称找 GAC,找不到再去应用目录。如果 bin 目录里根本没有 MySql.Data.dll,或者 Copy Local 没生效,就会报找不到;如果 GAC 里有不同版本,也可能加载错版本然后抛版本不匹配。
解决分三步。第一步查 bin 输出目录,确认 MySql.Data.dll 是否真的在,没有就先解决Private=True和清理重建。第二步确认 GAC 里有没有其他版本的 MySql.Data,有就先卸载脏版本。第三步,如果项目里其他库编译时绑定了更高版本,可以通过 binding redirect 临时收敛到 6.8.3.0,但这是过渡手段,治本还是统一全链路的版本。
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="MySql.Data" publicKeyToken="c5687fc88969c44d" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-6.9.99.99" newVersion="6.8.3.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>这个配置的含义是把 0.0.0.0 到 6.9.99.99 范围内请求的 MySql.Data 全部重定向到 6.8.3.0。我不建议长期靠它过日子,因为新版驱动可能用了旧版没有的 API,重定向后照样崩。正确姿势是:定位是哪个库引了高版本,把它也换回 6.8.3 对应版本,redirect 只用来兜底。
5.2 现象:EF6 迁移报 "The provider 'MySql.Data.MySqlClient' is not registered"
Enable-Migrations 或 Update-Database 时,EF 直接说 provider 没注册。这个现象最容易误导人,因为你明明在 DbProviderFactories 里注册过了。原因是 EF6 和 EF5 的 provider 发现机制不一样:EF6 不再从 DbProviderFactories 找 provider,它看的是entityFramework配置节里的providers列表。两处配置缺一个,EF 就不认识 MySQL。
解决要点是核对三处一致性:bin 目录里的 dll、entityFramework/providers里 type 字符串的程序集名和版本、连接串的 providerName。第 4 章的配置片段可以直接套用,注意 EF6 对应的是 MySql.Data.EntityFramework.dll,如果 bin 里只有 EF5 的 MySql.Data.Entity.dll,这个配置就必炸。
另一个同源坑是 DbConfiguration 冲突:项目里同时引了 EF5 和 EF6 两个集成程序集,EF6 启动时会发现多个 DbConfiguration 实例,直接抛异常。解决方法是只保留一套,然后显式声明用哪个:
[DbConfigurationType(typeof(MySqlEFConfiguration))] public class AppDbContext : DbContext { public AppDbContext() : base("name=mysqlConn") { } }这段代码里的MySqlEFConfiguration是驱动自带的配置类型,属性放在 DbContext 子类上,EF6 启动时就会按这个类型加载 MySQL 的 provider 配置而不是去瞎猜。如果项目里有多个 DbContext,记得所有上下文类都标上同一个属性,或者用DbConfiguration.SetConfiguration在程序入口统一设置。
5.3 现象:连接 MySQL 8.0 报 "Authentication method 'caching_sha2_password' not supported"
驱动还是 6.8.3,服务器换成了 MySQL 8.0,连接直接失败,报认证方法不支持。原因很清楚:MySQL 8.0 把默认认证插件改成了 caching_sha2_password,而 6.8.3 的年代只认识 mysql_native_password。这不是连接串问题,是协议协商层面的不兼容。
解决有两个方向。方向一,如果你必须留 6.8.3,那就把应用账号的认证插件改回旧协议。在 MySQL 8 上执行:
ALTER USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY 'yourpass';改完用第 3 章的代码测试连接,一般立刻恢复。注意这只影响指定账号,不会动服务器全局配置,风险可控。方向二,如果服务器政策不允许旧认证插件,那就只能换新版本驱动。两害相权,我的建议是先查公司对认证插件的安全要求,没有强制要求就改账号,因为换驱动意味着第 2.3 节说的 SslMode 默认值、连接池行为全都要重新验证一遍。
5.4 现象:连接老 MySQL 卡死或报 "Authentication to host failed" 且没有详细错误
连接串没写 SslMode,连一台 SSL 配置不完整的服务器,表现为两种:要么请求超时,要么在握手阶段失败,报错信息含糊像网络问题。排查半天发现根本不是网络。原因是 6.8.3 的 SslMode 默认是 Preferred,服务器支持 SSL 时驱动会尝试协商,而老版本 MySQL 的自签证书、低版本 TLS 组合很容易在协商中失败。
解决很简单:连接串显式写SslMode=None先做排除,如果确认是 SSL 协商问题,再按需决定是保持明文还是配置真证书。生产环境如果要加密,正确做法是SslMode=VerifyCA并配上证书,而不是继续用 Preferred 赌它协商成功。这里有一个明确的边界要讲清楚:SslMode=None意味着流量明文,在隔离内网可以接受,在公网环境必须换 VerifyCA。别为了省事把 None 带到公网部署上,那是给自己埋雷。
5.5 现象:同一台机器装了 MSI 又用 zip,DbProviderFactories 拿到的是另一个版本
机器上有过 MSI 版连接器,后来你又部署了 noinstall 版的项目,运行时发现工厂类返回的版本是 6.9.x 而不是 6.8.3。原因就是 MSI 在安装时写死了 machine.config 的 DbProviderFactories 节点,版本号指向 MSI 装的版本;你在 app.config 里 remove 再 add,只是覆盖了当前应用,IIS 里别的站点没做同样处理就仍然读机器配置。
解决的核心是"应用级覆盖要每个应用各自做"。给受影响的每个站点的 web.config 都加上第 4.3 节的 remove + add 片段。如果整机都想统一到 6.8.3,那就直接改 machine.config,但要先做好备份,改完立刻用 4.4 节的验证命令分别测 32 位和 64 位两个文件。还有一个更省事的策略:把 MSI 行为导致的脏 GAC 清理掉,用 gacutil /u 和 app.config 覆盖组合拳之后,这台机器的 MySQL 驱动生态就完全在你的掌控下了。
6. 把 noinstall 变成团队基建:指纹校验与版本固化
noinstall 包最大的风险不是技术,是"来个新同事,不知道用哪个版本、从哪拿的文件"。最后一章给三个具体动作,把这件事从个人经验变成团队资产。
第一个动作:给 zip 做哈希指纹。部署包在群里传来传去,最怕有人从某个不可考的渠道重新下载了一份。拿到 zip 的第一件事就是算哈希,和已知值比对,不一致直接拒收,不要打开看。
Get-FileHash "mysql-connector-net-6.8.3-noinstall.zip" -Algorithm SHA256这个命令输出一个 64 位十六进制字符串,把它固化进项目 README。以后任何人接手,第一步就是跑这条命令确认文件没被掉包。文件版本号可以伪造,哈希做不了假。
第二个动作:把版本固化进私有源。常见做法是把驱动打包成内部 nupkg 放进离线 NuGet 源,团队所有项目统一从这个源引用。这样 6.8.3 的 dll、版本号、依赖关系全都有记录,不再依赖个人 U 盘。内部源的稳定意义大于省事意义:它让"这个项目为什么锁 6.8.3"这件事在包管理器的历史里可追溯。
第三个动作:维护一份三分钟验证清单。任何环境部署完,照着清单跑一遍再交付,比事后接到故障电话强十倍。
| 检查项 | 方法 | 期望结果 |
|---|---|---|
| dll 版本 | 2.2 节 PowerShell | Version=6.8.3.0 |
| bin 输出 | 查看 bin 目录 | 存在 MySql.Data.dll |
| 连接测试 | 3.3 节代码 | SELECT 正常返回 |
| 工厂注册 | 4.4 节 GetFactory | 返回 6.8.3.0 |
| EF 迁移 | Update-Database -Verbose | 无 provider 报错 |
我的习惯是把这份清单写进部署文档的第一页,每次交付都按顺序过一遍。6.8.3 这个版本的坑基本都踩过一遍之后,你会发现 noinstall 包反而比 MSI 更可控——装了什么、注册了什么、每个文件在哪,全都清清楚楚。希望帮到你。
本文还有配套的精品资源,点击获取