连接字符串错误是连不上MySQL的最常见原因,需显式指定Server、Port、Database、Uid、Pwd,并注意MySQL 8.0+认证插件兼容性及权限配置。

MySqlConnection 连接字符串写不对,连不上是大概率事件
连不上 MySQL 最常见的原因是连接字符串格式错误或权限配置没到位。C# 里 MySqlConnection 不会自动帮你校验账号密码是否有效、端口是否开放、用户是否有库表权限——它只负责把字符串发给驱动,失败就直接抛异常。
实操建议:
- 用
Server=localhost;Port=3306;Database=testdb;Uid=root;Pwd=123456;这种显式写法,别省略Port(默认 3306,但 Docker 或远程部署时经常改) -
Uid和Pwd要对应 MySQL 中CREATE USER创建的账号,不是操作系统用户;如果用的是 MySQL 8.0+,确认该用户认证插件是caching_sha2_password还是mysql_native_password—— .NET 的 MySqlConnector 默认支持前者,但旧版MySql.Data可能需要显式指定AuthenticationMethod=MySQLNativePassword - 连接前先用命令行验证:
mysql -h 127.0.0.1 -P 3306 -u root -p,能登进去再写 C# 代码
MySqlCommand 执行 INSERT/UPDATE 一定要用参数化查询
拼接 SQL 字符串(比如 "INSERT INTO users VALUES ('" + name + "')" )在 C# 里等于主动邀请 SQL 注入和类型转换崩溃。MySQL 驱动对参数绑定支持很稳,没必要冒险。
实操建议:
- 所有用户输入、变量值,一律走
Parameters.AddWithValue("@name", name),不要用字符串插值或string.Format - 注意参数名要带
@前缀(MySqlConnector和MySql.Data都要求),且和 SQL 中占位符严格一致 - 执行非查询语句(INSERT/UPDATE/DELETE)用
ExecuteNonQuery(),返回影响行数;查数据用ExecuteReader()或ExecuteScalar(),别混用
using var conn = new MySqlConnection(connStr);
conn.Open();
using var cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO logs (msg, ts) VALUES (@msg, @ts)";
cmd.Parameters.AddWithValue("@msg", "test");
cmd.Parameters.AddWithValue("@ts", DateTime.Now);
cmd.ExecuteNonQuery(); // 返回 1MySqlDataReader 读取时字段名大小写敏感,且不能重复调用 Read()
MySQL 表字段名默认不区分大小写,但 MySqlDataReader 返回的列名(reader["Id"])取决于驱动如何解析元数据——在 Linux 上建的表,字段是 id,代码里写 reader["ID"] 就会报 IndexOutOfRangeException。
实操建议:
- 读取字段优先用索引(
reader.GetInt32(0))或统一小写字段名(建表时全用小写,代码里也用小写),避免靠猜 -
Read()是游标前进操作,每调一次移向下一行;写成while (reader.Read()) { ... reader.Read(); }会跳过奇数行 - 别在
using外访问reader,它依赖底层连接,连接一释放就读不到数据
异步方法如 ExecuteReaderAsync 必须 await,否则线程卡死或连接泄漏
MySqlConnection 的异步 API(OpenAsync、ExecuteReaderAsync 等)不是“锦上添花”,而是防止 I/O 阻塞线程池的关键路径。同步调用(比如在 ASP.NET Core 控制器里用 ExecuteReader())会导致请求线程挂起,高并发下迅速耗尽线程资源。
实操建议:
- 所有数据库操作入口必须是
async Task<t></t>,调用链顶端(如 Controller Action)标记async,中间每一步都await - 别用
.Result或.Wait()强转同步——这在 UI 线程或 ASP.NET 同步上下文里大概率死锁 - 连接对象本身不跨请求复用,每次操作新建
MySqlConnection实例(连接池自动管理底层物理连接)
最易被忽略的一点:MySQL 驱动版本和连接池行为强相关。MySqlConnector 2.x 默认启用连接池,但 MySql.Data 有些老版本需要手动加 Pooling=true 到连接字符串里,否则每次新建物理连接,性能断崖下跌。


















