.Net无法连接Docker容器内MariaDB的问题排查求助
尝试连接Docker容器内的MariaDB数据库,查阅官方文档和搜索后仍未解决“无法从数据库获取数据”的问题。调试发现数据库校验代码未执行,错误发生在conn.Open();行后程序终止。Docker显示已建立连接,但抛出以下错误:
System.InvalidCastException: 'Object cannot be cast from DBNull to other types.'
同时Docker终端出现提示:
Aborted connection 3 to db: 'userDB' user: 'root' host: 'REMOVED' (Got an error reading communication packets)
相关代码与配置如下:
.Net代码
using MySql.Data.MySqlClient; namespace DockerBase { internal class UserDB { public bool ValidateUser(string username, string password) { try { MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(); builder.Server = "localhost"; builder.Port = 3306; builder.UserID = "root"; builder.Password = "rootpassword"; builder.Database = "userDB"; using (MySqlConnection conn = new MySqlConnection(builder.ConnectionString)) { conn.Open(); string sql = "SELECT COUNT(*) FROM users WHERE username = @username AND password = @password;"; int result = 0; using (MySqlCommand cmd = new MySqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@username", username); cmd.Parameters.AddWithValue("@password", password); result = Convert.ToInt32(cmd.ExecuteScalar()); } bool isValid = (result > 0); return isValid; } } catch (MySqlException e) { Console.WriteLine("Error connecting to MySQL database: " + e.Message); return false; } } } }
Dockerfile
FROM mariadb:latest ENV MYSQL_DATABASE=userDB ENV MYSQL_USER=myuser ENV MYSQL_PASSWORD=mypassword ENV MYSQL_ROOT_PASSWORD=rootpassword # Copy SQL scripts COPY createUser.sql /docker-entrypoint-initdb.d/ EXPOSE 3306
SQL初始化脚本
USE userDB; DROP TABLE IF EXISTS users; CREATE TABLE users ( username VARCHAR(50) NOT NULL, password VARCHAR(50) NOT NULL, ); INSERT INTO users (username, password) VALUES ('admin', 'admin');
1. SQL初始化脚本语法错误
你的createUser.sql中创建表的语句最后一列后多了一个逗号,这会导致MariaDB执行脚本失败,users表无法正常创建:
CREATE TABLE users ( username VARCHAR(50) NOT NULL, password VARCHAR(50) NOT NULL, -- 多余的逗号引发语法错误 );
解决方法:删除该逗号,修正后的建表语句:
CREATE TABLE users ( username VARCHAR(50) NOT NULL, password VARCHAR(50) NOT NULL );
重新构建镜像并启动容器,确保users表被正确创建。
2. 异常捕获范围不足
代码仅捕获MySqlException,但实际抛出的InvalidCastException不在捕获范围内,导致程序直接终止。当users表不存在时,ExecuteScalar()可能返回DBNull,执行Convert.ToInt32()时就会触发这个异常。
解决方法:扩展异常捕获范围,添加对InvalidCastException及通用异常的捕获:
try { // 原有代码... } catch (MySqlException e) { Console.WriteLine("Database connection error: " + e.Message); return false; } catch (InvalidCastException e) { Console.WriteLine("Data conversion error: " + e.Message); return false; } catch (Exception e) { Console.WriteLine("Unexpected error: " + e.Message); return false; }
这样可以捕获所有异常并输出详细信息,便于排查问题。
3. 容器端口映射检查
如果.Net程序在本地运行,需确保启动MariaDB容器时做了端口映射,否则本地localhost:3306无法访问容器内的数据库:
docker run -p 3306:3306 your-mariadb-image-name
替换your-mariadb-image-name为你的镜像名称。
4. 验证数据库初始化结果
进入容器确认userDB库和users表是否存在:
docker exec -it your-container-name mysql -u root -p
输入密码后执行以下命令:
USE userDB; SHOW TABLES;
如果输出中包含users表,说明初始化成功;否则需检查脚本是否正确执行。
5. Docker连接中断错误解释
Aborted connection...错误通常是客户端连接后因异常(如查询不存在的表)导致中断,修正SQL脚本和代码后,这个问题会随之解决。
内容的提问来源于stack exchange,提问作者Terrell-byte

