You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:27:49