MySqlConnector连接字符串需显式设SslMode=None,连接须手动Open(),异步调用要ConfigureAwait(false),读取字段用GetName或序号,TINYINT(1)映射bool需注意类型匹配。
MySqlConnector 连接字符串怎么写才不报错
连接失败八成是连接字符串格式不对,尤其是端口、数据库名、ssl 设置这三项。mysqlconnector 默认要求 ssl,但本地开发环境通常没配证书,直接连会抛 mysqlexception: ssl connection error。
- 最简可用连接字符串(禁用 SSL):
"Server=localhost;Port=3306;Database=testdb;Uid=root;Pwd=123456;SslMode=None;" -
SslMode=None必须显式声明,不能省略;SslMode=Preferred在某些 MySQL 8.0+ 版本下仍会尝试握手失败 - 用户名密码别硬编码,改用
MySqlConnectionStringBuilder拼装,避免拼错引号或分号:var builder = new MySqlConnectionStringBuilder { Server = "localhost", Database = "testdb", UserID = "root", Password = "123456", SslMode = MySqlSslMode.None }; - Windows 上若用命名管道或 Unix socket,路径要写对:
Socket=/var/run/mysqld/mysqld.sock(Linux)或Pipe=my_pipe_name(Windows)
为什么 new MySqlConnection() 后 ExecuteReader 报“Connection must be Open”
MySqlConnector 不像旧版 MySql.Data 那样自动打开连接,Open() 必须手动调用,且不能依赖 using 块自动管理——因为 using 会提前释放连接对象,导致后续读取失败。
- 正确写法:先
connection.Open(),再command.ExecuteReader(),且 reader 使用完前 connection 不能 dispose - 推荐用嵌套 using 确保顺序:
using var connection = new MySqlConnection(builder.ConnectionString);<br>connection.Open();<br>using var cmd = new MySqlCommand("SELECT * FROM users", connection);<br>using var reader = cmd.ExecuteReader();<br>while (reader.Read()) { ... } - 如果用
ExecuteScalar()或ExecuteNonQuery(),也必须保证 connection 已 Open,否则一律抛InvalidOperationException: Connection must be Open
异步方法(ExecuteReaderAsync)卡住不动?检查线程上下文
在 WinForms 或 WPF 的 UI 线程里直接 await ExecuteReaderAsync() 容易死锁,因为默认的 ConfigureAwait(true) 试图切回原上下文,而 UI 线程可能正被同步等待阻塞。
- UI 应用中务必加
.ConfigureAwait(false):var reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false);
- ASP.NET Core 项目默认无同步上下文,可以不用配,但加上更稳妥
- 别混用同步和异步:比如
connection.Open()+await cmd.ExecuteReaderAsync()是安全的;但await connection.OpenAsync()+cmd.ExecuteReader()就可能出问题——连接状态不一致 - MySqlConnector 的异步方法底层基于 SocketAsyncEventArgs,性能比同步高,但仅当整个调用链都异步时才真正生效
查询结果读不到数据?注意 MySqlDataReader 的字段索引和类型映射
MySqlDataReader 默认按列定义顺序返回字段,但如果你 SELECT 里用了别名、函数或表达式(如 COUNT(*) AS total),reader["total"] 可能找不到,因为字段名不等于别名——它取决于 MySQL 实际返回的 column name。
- 查字段名用
reader.GetName(i),而不是猜名字;或者统一用序号:reader.GetInt32(0) - MySQL 的
TINYINT(1)默认被映射为bool,但如果你用的是tinyint unsigned存状态码,reader.GetBoolean()会崩,得用reader.GetByte() - 日期字段若含毫秒(MySQL 5.6.4+ 支持
DATETIME(3)),reader.GetDateTime()会丢精度,应改用reader.GetMySqlDateTime()再转DateTime - 空值处理别用
== null,要用IsDBNull()判断,否则遇到 NULL 会抛InvalidCastException
连接本身不难,难的是 MySQL 和 .NET 类型之间那些隐式转换规则、SSL 协商时机、以及异步上下文切换的边界条件——这些地方一不留神就进坑,而且错误信息还特别模糊。











