如何以正确的方式管理 mysql 连接而不出错
How to manage the mysql connection in correct way without getting a error
我是 C# 新手,我的方法在 try catch
connection is already open
代码中显示如下错误,当我从 Class 方法关闭它时,Form 收到错误 invalid connection
。在这里,如果将所有代码放在 FORM 中,它就可以工作。但在这里我得到 MysqlDataReader
作为 return 值。我该如何解决这个错误。
CLASS
//select all categories
public MySqlDataReader SelectCategory() {
try
{
MySqlCommand cmd = connection.CreateCommand();
cmd.CommandText = "SELECT * FROM categories WHERE online = 1";
connection.Open();
MySqlDataReader categories = cmd.ExecuteReader();
return categories;
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
return null;
}
}
表格
public void show()
{
MySqlDataReader rd = db.SelectCategory();
try
{
while (rd.Read())
{
listBox1.Items.Add(rd.GetString(1));
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
我会使用 using
,它关心处理变量和关闭连接。
CLASS:
public List<string> SelectCategory()
{
List<string> result = new List<string>();
string Command = "SELECT * FROM categories WHERE online = 1";
using (MySqlConnection mConnection = new MySqlConnection(ConnectionString))
{
mConnection.Open();
using (MySqlCommand cmd = new MySqlCommand(Command, mConnection))
{
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(reader.GetString(1));
}
}
}
}
return result;
}
表格:
public void show()
{
try
{
foreach(string item in SelectCategory())
{
listBox1.Items.Add(item);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
DataReader
是用于从数据库检索数据的例外情况,它始终需要打开连接才能从 DataReader 获取值。在您的情况下,您将 MySqlDataReader
传递给调用方法,因此您无法关闭被调用方法的连接,因为 reader 需要打开的连接。所以你的可能性是在关闭 DataReader
.
后关闭连接
您可能面临的另一个问题是连接问题(您当前的问题),从您的代码可以看出您没有关闭连接,因此当您第一次调用该方法时,一切都会好起来的。当第二次调用触发时,连接的当前状态将打开,因此当您尝试重新打开连接时它会抛出此类异常。
别担心,您可以使用以下任一方法来解决问题(我不确定这些建议是否对这个社区有效,如果不是请见谅)
- 将您的 UI 控件传递给 class 方法并将项目添加到列表
在这种情况下,该方法是在另一个 class 中定义的,因此无法在那里使用 UI 项,因此更好的选择是传递 UI 元素, ListBox 添加到该方法并使用 reader 填充它。为此,代码将是这样的:
public MySqlDataReader SelectCategory(ListBox listBox1)
{
// fubo's answer here
}
- 在检查连接状态后生成一个关闭连接的方法,并在 while 完成其迭代时调用该方法。
调用方法如下:
try
{
using (MySqlDataReader reader = db.SelectCategory())
{
while (reader.Read())
{
listBox1.Items.Add(reader.GetString(1));
}
}
db.CloseConnection(); // will be the method to close the connection
}
- 使用 DataTable 代替 DataReader:
将数据获取到 DataTable,然后使用该 DataTable
绑定所需的列表
始终使用 finally 关闭连接,无论发生什么情况,打开后都必须关闭连接。
public MySqlDataReader SelectCategory() {
try
{
MySqlCommand cmd = connection.CreateCommand();
cmd.CommandText = "SELECT * FROM categories WHERE online = 1";
connection.Open();
MySqlDataReader categories = cmd.ExecuteReader();
return categories;
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
return null;
}
finally
{
if (connection != null && connection.State == ConnectionState.Open)
{
connection.Close();
connection.Dispose();
}
}
}
我是 C# 新手,我的方法在 try catch
connection is already open
代码中显示如下错误,当我从 Class 方法关闭它时,Form 收到错误 invalid connection
。在这里,如果将所有代码放在 FORM 中,它就可以工作。但在这里我得到 MysqlDataReader
作为 return 值。我该如何解决这个错误。
CLASS
//select all categories
public MySqlDataReader SelectCategory() {
try
{
MySqlCommand cmd = connection.CreateCommand();
cmd.CommandText = "SELECT * FROM categories WHERE online = 1";
connection.Open();
MySqlDataReader categories = cmd.ExecuteReader();
return categories;
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
return null;
}
}
表格
public void show()
{
MySqlDataReader rd = db.SelectCategory();
try
{
while (rd.Read())
{
listBox1.Items.Add(rd.GetString(1));
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
我会使用 using
,它关心处理变量和关闭连接。
CLASS:
public List<string> SelectCategory()
{
List<string> result = new List<string>();
string Command = "SELECT * FROM categories WHERE online = 1";
using (MySqlConnection mConnection = new MySqlConnection(ConnectionString))
{
mConnection.Open();
using (MySqlCommand cmd = new MySqlCommand(Command, mConnection))
{
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(reader.GetString(1));
}
}
}
}
return result;
}
表格:
public void show()
{
try
{
foreach(string item in SelectCategory())
{
listBox1.Items.Add(item);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
DataReader
是用于从数据库检索数据的例外情况,它始终需要打开连接才能从 DataReader 获取值。在您的情况下,您将 MySqlDataReader
传递给调用方法,因此您无法关闭被调用方法的连接,因为 reader 需要打开的连接。所以你的可能性是在关闭 DataReader
.
您可能面临的另一个问题是连接问题(您当前的问题),从您的代码可以看出您没有关闭连接,因此当您第一次调用该方法时,一切都会好起来的。当第二次调用触发时,连接的当前状态将打开,因此当您尝试重新打开连接时它会抛出此类异常。
别担心,您可以使用以下任一方法来解决问题(我不确定这些建议是否对这个社区有效,如果不是请见谅)
- 将您的 UI 控件传递给 class 方法并将项目添加到列表
在这种情况下,该方法是在另一个 class 中定义的,因此无法在那里使用 UI 项,因此更好的选择是传递 UI 元素, ListBox 添加到该方法并使用 reader 填充它。为此,代码将是这样的:
public MySqlDataReader SelectCategory(ListBox listBox1)
{
// fubo's answer here
}
- 在检查连接状态后生成一个关闭连接的方法,并在 while 完成其迭代时调用该方法。
调用方法如下:
try
{
using (MySqlDataReader reader = db.SelectCategory())
{
while (reader.Read())
{
listBox1.Items.Add(reader.GetString(1));
}
}
db.CloseConnection(); // will be the method to close the connection
}
- 使用 DataTable 代替 DataReader: 将数据获取到 DataTable,然后使用该 DataTable 绑定所需的列表
始终使用 finally 关闭连接,无论发生什么情况,打开后都必须关闭连接。
public MySqlDataReader SelectCategory() {
try
{
MySqlCommand cmd = connection.CreateCommand();
cmd.CommandText = "SELECT * FROM categories WHERE online = 1";
connection.Open();
MySqlDataReader categories = cmd.ExecuteReader();
return categories;
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
return null;
}
finally
{
if (connection != null && connection.State == ConnectionState.Open)
{
connection.Close();
connection.Dispose();
}
}
}