C# Mysql Connection must be valid and open

≯℡__Kan透↙ 提交于 2019-12-04 21:58:17

The problem is that you don't store the connection that was returned from your factory property. But don't use a property like a method. Instead use it in this way:

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

So use the same connection in the using that was returned from the property(or better created in the using) and pass it to the method which uses it. By the way, using a property as factory method is not best practise.

But in my opinion it's much better to create the connection where you use it, best place is in the using statement. And throw the con property to the garbage can, it is pointless and a source for nasty errors.

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);
    }
}

Try to restructure your Services class as follows

   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);
            }
        }

In LoginForm.cs use returning connection and store it there. When you need to execute query, use

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

Additional - I suggest you need to return MySqlDataReader to LoginForm and handle results there

BoeseB
private MySqlConnection _conn;
public MySqlConnection conn // Returns the connection itself
        {
            get
            {
               if(_conn == null)
                 _conn = new MySqlConnection(Services.ServerConnection);
                return _conn;
            }
        }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!