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);
}
}
首先:我在没有使用 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);
}
}