C# 无法连接到远程主机

C# 无法连接到远程主机,c#,mysql,database,C#,Mysql,Database,连接到远程主机时出现问题。我可以使用数据库副本连接到本地服务器 我正在尝试连接到web主机上的XenForo DB并获取一些信息。所有这些都在本地主机上运行 private static MySqlConnection _connection = new MySqlConnection("Server=ip; database=ls-v_forum; UID=ls-v_forum; password=pass"); public static int? FetchUserId(str

连接到远程主机时出现问题。我可以使用数据库副本连接到本地服务器

我正在尝试连接到web主机上的XenForo DB并获取一些信息。所有这些都在本地主机上运行

private static MySqlConnection _connection = 
    new MySqlConnection("Server=ip; database=ls-v_forum; UID=ls-v_forum; password=pass");

public static int? FetchUserId(string emailoruser)
{
    MySqlCommand userCommand = new MySqlCommand("SELECT * FROM xf_user WHERE username='" + emailoruser + "'", _connection);
    MySqlCommand emailCommand = new MySqlCommand("SELECT * FROM xf_user WHERE email='" + emailoruser + "'", _connection);

    _connection.OpenAsync();
}
这就是代码,它抛出了这个错误

连接必须有效且打开。 位于MySql.Data.MySqlClient.ExceptionInterceptor.Throw(异常) 在MySql.Data.MySqlClient.MySqlCommand.CheckState()中 位于MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior (行为)

编辑

public int? FetchUserId(string emailoruser)
    {
        using (var _connection = new MySqlConnection("server=ip; database=ls-v_forum; UID=ls-v_forum; password=pass"))
        {
            MySqlCommand userCommand = new MySqlCommand("SELECT * FROM xf_user WHERE username='" + emailoruser + "'", _connection);
            MySqlCommand emailCommand = new MySqlCommand("SELECT * FROM xf_user WHERE email='" + emailoruser + "'", _connection);

            _connection.Open();


            MySqlDataReader userReader = userCommand.ExecuteReader();

            int? userId = null;

            while (userReader.Read())
            {
                userId = userReader.GetInt32("user_id");
            }

            userReader.Close();

            if (userId == null || userId == 0)
            {
                MySqlDataReader emailReader = emailCommand.ExecuteReader();

                while (emailReader.Read())
                {
                    userId = emailReader.GetInt32("user_id");
                }

                emailReader.Close();
            }

            _connection.Close();

            return userId;
        }
    }
MySql.Data.MySqlClient.MySqlException(0x80004005):无法连接到任何 指定的MySQL主机的名称。 在MySql.Data.MySqlClient.NativeDriver.Open()上 在MySql.Data.MySqlClient.Driver.Open()上 位于MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder 设置) 在MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()上 在MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()上 在MySql.Data.MySqlClient.MySqlPool.TryToGetDriver()上 在MySql.Data.MySqlClient.MySqlPool.GetConnection()上 在MySql.Data.MySqlClient.MySqlConnection.Open()上


我没有尝试对您的connection命令进行故障排除,但在连接到远程计算机上的SQL DB时,以下操作对我有效

即使是本地机器,也可以提供机器名,因此,如果程序与数据库在同一台机器上运行,或者如果程序在一台机器上运行,而数据库在另一台机器上运行,则下面的代码将起作用,只要两台机器联网,并且运行程序的帐户可以访问机器、实例和数据库

请注意,在下面的示例中,安装SQL时使用了“默认”实例名(MSSQLSERVER)。如果DB实例名称是默认名称,则不能显式提供实例名称(如果提供,则会出错)。只有当实例名称不是默认实例名称时,才显式提供实例名称。下面的代码可以处理任何一种情况(通过将dbInstanceName变量设置为“”或实例名称,例如“\SQLEXPRESS”)。请参阅S.O.SQL Server:如何查找所有localdb实例名称。当它有疑问时,尝试一个空的实例名和一个您认为是实例名的名称,看看什么是有效的

string databaseMachineName = "machine_name";
string databaseInstanceName = ""; 
string dbName = "database_name";

using (SqlConnection sqlConnection = new SqlConnection("Data Source=" + databaseMachineName + databaseInstanceName + "; Initial Catalog=" + dbName + "; Integrated Security=True;Connection Timeout=10"))
{
   .
   .
   .
}
连接到远程主机时出现问题

不一定。根据错误,问题不是你不能连接。这是因为您试图使用未连接的连接:

连接必须有效且打开

特别是在执行命令时:

MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior)

这不在您显示的代码中。但是,您所展示的代码中有几个基本错误,它们很容易导致如下错误:

1。使用静态共享连接对象。

这是一个众所周知的坏主意。我们可能都试过,也可能都遇到过类似的问题。底层系统在创建/池化/使用/处理数据库连接方面非常高效。不要试图对此进行优化。相反,您应该在尽可能小的范围内创建/使用/处置连接。例如:

using (var  connection = new MySqlConnection(SOME_CONNECTION_STRING))
{
    var userCommand = new MySqlCommand(SOME_COMMAND_STRING);
    // use the command, get the data you need from it
}
// leave the context of the database and return to business logic, UI, etc.
这是因为保持数据库连接等复杂事物的同步是困难的,而保持连接的开放是昂贵的。让基础系统打开/池/关闭连接

2。不等待异步操作。

这里会发生什么

connection.OpenAsync();
userCommand.ExecuteNonQuery();
一个错误。因为代码没有等待异步操作,所以当您尝试使用它时,连接没有打开。或者不使用异步操作:

connection.Open();
userCommand.ExecuteNonQuery();
或者等待它:

await connection.OpenAsync();
userCommand.ExecuteNonQuery();
(显然,要使包含方法
异步,其调用者应该等待它,等等),但绝对不要在有机会打开之前尝试使用连接

3。(不相关,但仍然很重要)您的代码易受SQL注入攻击。

SQL注入就发生在这里:

"SELECT * FROM xf_user WHERE username='" + emailoruser + "'"

emailoruser
来自哪里?是用户输入的吗?它是从用户以前提供的数据中提取的值吗?它有多值得信赖?这种字符串连接方法的作用是允许任何用户在数据库上执行他们想要的任何SQL代码。相反,请将用户输入视为值而不是可执行代码。

尝试不使用异步方式打开连接_connection.Open()。如果您试图将singleton实现为一个连接,那么静态可能会导致问题,重构它。似乎您必须查询引用相同的静态连接,。。。我不确定是否有副作用,但先去掉异步模式和静态连接,然后再试一次。如果你想使用单连接对象,请使用单连接模式。谢谢你的回复。非常深入和有帮助。我现在就来解决你提到的问题。选择方法(emailoruser)是从游戏服务器内的文本框中引入的,他们输入用户或电子邮件,然后它会查找。谢谢@David,但是出现了一个错误。我已经在问题的“编辑”部分下发布了更改和错误。@Moretti:哪一行抛出了新错误?还是完全一样的错误吗?另外,我认为您不需要对代码中的任何对象调用
.Close()
。很抱歉,我没有输入正确的错误。它在Open()行
\u connection.Open()上