我试图连接到Docker容器中的Mariadb数据库。我查看了Microsoft的文档,并在Google上搜索,以找出为什么我会收到一条错误消息,说数据库中没有任何内容可检索。这很奇怪,因为当我尝试调试代码时,它不会执行检查数据库的行。错误发生在“conn.Open();“然后它就停止了。我还可以在Docker中看到它正在获取连接,所以连接字符串应该是正确的。有人能解释一下我做错了什么吗?
这是错误消息:
System.InvalidCastException:'对象不能从DBNull转换为其他类型。'
下面是我的代码:
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');
在Dockerhub的终端中,我可以看到正在进行连接:
已中止到数据库的连接% 3:'userDB'用户:“根”主机:'REMOVED'(阅读通信数据包时出错)
3条答案
按热度按时间4c8rllxm1#
builder.Server = "localhost";
更改此行,使其包含您的容器名称,而不是localhost,如下所示:
builder.Server = "mysql-container-name";
这是由于Docker容器不共享localhost。
14ifxucb2#
我们有这个错误消息:
System.InvalidCastException:'对象不能从DBNull转换为其他类型。'
具体来说
DBNull
是NOTMySQL数据库知道的一个概念。它是客户端**.Net代码中的一个特殊值,用于表示从SQL查询返回的NULL
。它需要作为一个与普通C#null
引用不同的项,因为int
和DateTime
等原始值类型不支持int
和DateTime
。没有自己的null
概念来Map到相应的SQLInteger
和Datetime
类型,并且ADO.Net库早于.Net可空值类型(int?
、DateTime?
等)。因此,您可能得到此错误的唯一方法是 * 在您成功运行查询之后。* 换句话说,连接正常工作并完成,并且错误发生在
ExecuteScalar()
调用完成之后。最有可能的是,
COUNT(*)
表达式(不知何故)在SQL端产生NULL
,ADO.Net将其表示为DBNull.Value
(对于C#)和theConvert.ToInt32()
function doesn't know what to do with this。这与不返回任何行不同。The
ExecuteScalar()
function should return a basic C#null
reference if the result set is empty,如果没有行,则与DBNull
不同。pn9klfpd3#
问题是使用mariadb的一些东西。当我再次按下登录按钮时,它就会工作,所以第一个连接现在已经完全建立。我更改了Dockerfile,以便它使用最新版本的MySQL,从而解决了问题。