C# Mysql 连接必须有效且打开

C# Mysql Connection must be valid and open

首先:我在没有使用 oop 的情况下获得了我的代码 运行。在将查询传递给数据库之前和之后,我在相同的 class 和 opened/closed 连接中声明了所有变量。成功了!现在有了一些新的经验,我尝试将我的代码拆分成不同的 classes。现在它不再起作用了。

它告诉我"Connection must be valid and open"。足够的文本,这是我当前的代码:


Services.cs

public static MySqlConnection conn // Returns the connection itself
        {
            get
            {
                MySqlConnection conn = new MySqlConnection(Services.ServerConnection);
                return conn;
            }
        }

public static string ServerConnection // Returns the connectin-string
        {
            get
            {    
                return String.Format("Server={0};Port=XXXX;Database=xxx;Uid=xxx;password=xxXxxXxXxxXxxXX;", key);
            }
        }

public static void DB_Select(string s, params List<string>[] lists)
        {
            try
            {
                MySqlCommand cmd = conn.CreateCommand();
                cmd.CommandType = CommandType.Text;
                string command = s;
                cmd.CommandText = command;
                MySqlDataReader sqlreader = cmd.ExecuteReader();
                while (sqlreader.Read())
                {
                    if (sqlreader[0].ToString().Length > 0)
                    {
                        for (int i = 0; i < lists.Count(); i++)
                        {
                            lists[i].Add(sqlreader[i].ToString());
                        }
                    }
                    else
                    {
                        foreach (List<string> save in lists)
                        {
                            save.Add("/");
                        }
                    }
                }
                sqlreader.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error while selecting data from database!\nDetails: " + ex);
            }
        }

LoginForm.cs

private void checkUser(string username, string password)
        {
        using (Services.conn)
                    {
                        Services.conn.Open();
                        Services.DB_Select("..a short select statement..");
                        Services.conn.Close();
                    }

我想这就是我们所需要的。我缩短了我的代码以关注问题。

我创建了 Services.cs 以获得一种全局方式来从所有表单访问数据库,而无需复制和粘贴连接信息。现在,当我到达 LoginForm.cs 时,它会抛出一个错误 "Connection must be valid and open"。我已经调试了我的代码。时间都关闭了。即使通过 conn.Open() 它也会保持关闭状态。为什么?

另一个尝试: 我也试过将 conn.Open()conn.Close() 放在 Services.DB_Select(..) 的开头和结尾。同样的错误。

我不得不说:代码之前有效,我使用了相同的连接字符串。所以字符串本身肯定是有效的。

非常感谢此处提供的任何帮助!

private MySqlConnection _conn;
public MySqlConnection conn // Returns the connection itself
        {
            get
            {
               if(_conn == null)
                 _conn = new MySqlConnection(Services.ServerConnection);
                return _conn;
            }
        }

尝试按如下方式重组您的服务class

   public static MySqlConnection conn // Returns the connection itself
       {
            get
            {
                MySqlConnection conn = new MySqlConnection(Services.ServerConnection);
                return conn;
            }
        }

    private static string ServerConnection // Returns the connectin-string - PRIVATE [Improved security]
        {
            get
            {    
                return String.Format("Server={0};Port=XXXX;Database=xxx;Uid=xxx;password=xxXxxXxXxxXxxXX;", key);
            }
        }

 // Rather than executing result here, return the result to LoginForm - Future improvement
  public static void DB_Select(MySqlConnection conn ,string s, params List<string>[] lists)
        {
            try
            {
                MySqlCommand cmd = conn.CreateCommand();
                cmd.CommandType = CommandType.Text;
                string command = s;
                cmd.CommandText = command;
                MySqlDataReader sqlreader = cmd.ExecuteReader();
                while (sqlreader.Read())
                {
                    if (sqlreader[0].ToString().Length > 0)
                    {
                        for (int i = 0; i < lists.Count(); i++)
                        {
                            lists[i].Add(sqlreader[i].ToString());
                        }
                    }
                    else
                    {
                        foreach (List<string> save in lists)
                        {
                            save.Add("/");
                        }
                    }
                }
                sqlreader.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error while selecting data from database!\nDetails: " + ex);
            }
        }

在 LoginForm.cs 中使用 returning 连接并将其存储在那里。当需要执行查询时,使用

           MySqlConnection conn=Services.conn(); // Get a new connection
           Services.DB_Select(conn,"..a short select statement.."); // Executing requirement
           Services.conn.Close(); 

附加 - 我建议您需要 return MySqlDataReader 到 LoginForm 并在那里处理结果

问题是您没有存储从工厂返回的连接 属性。但是不要像方法一样使用 属性 。而是以这种方式使用它:

using (var con = Services.conn)
{
    Services.conn.Open();
    Services.DB_Select("..a short select statement..", con ));
    //Services.conn.Close(); unnecessary with using
}

因此,在使用中使用从 属性 返回的相同连接(或更好地在使用中创建)并将其传递给使用它的方法。顺便说一下,使用 属性 作为工厂方法并不是最佳实践。

在我看来,在您使用它的地方创建连接要好得多,最好的地方是在 using 语句中。并将 con 属性 扔进垃圾桶,这是毫无意义的,也是严重错误的来源。

public static void DB_Select(string s, params List<string>[] lists)
{
    try
    {
         using(var conn = new MySqlConnection(Services.ServerConnection))
         {
            conn.Open();
            MySqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = s;
            using( var sqlreader = cmd.ExecuteReader())
            while (sqlreader.Read())
            {
                if (sqlreader[0].ToString().Length > 0)
                {
                    for (int i = 0; i < lists.Count(); i++)
                    {
                        lists[i].Add(sqlreader[i].ToString());
                    }
                }
                else
                {
                    foreach (List<string> save in lists)
                    {
                        save.Add("/");
                    }
                }
            } // unnecessary to close the connection
        }     // or the reader with the using-stetement
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error while selecting data from database!\nDetails: " + ex);
    }
}