所以这有点像代码一样。
我有一个函数正在检查表中的最后一个ID,这个函数在另一个函数中调用。在该功能结束时,我有另一个功能,即打开另一个数据头。
错误:
已经有一个与此连接关联的打开的Datareader必须先关闭。
getLastIdfromDB()
public string getLastIdFromDB()
{
int lastIndex;
string lastID ="";
var dbCon = DB_connect.Instance();
if (dbCon.IsConnect())
{
MySqlCommand cmd2 = new MySqlCommand("SELECT ID FROM `competitor`", dbCon.Connection);
try
{
MySqlDataReader reader = cmd2.ExecuteReader();
while (reader.Read())
{
string item = reader2["ID"].ToString();
lastIndex = int.Parse(item);
lastIndex++;
lastID = lastIndex.ToString();
}
}
catch (Exception ex)
{
MessageBox.Show("Error:" + ex.Message);
}
}
return lastID;
}
此功能稍后在此功能中使用:
private void addPlayerBtn_Click(object sender, EventArgs e)
{
ListViewItem lvi = new ListViewItem(getLastIdFromDB());
.........................................^
... HERE
...
... irrelevant code removed
.........................................
var dbCon = DB_connect.Instance();
if (dbCon.IsConnect())
{
MySqlCommand cmd = new MySqlCommand("INSERT INTO `competitor`(`ID`, `Name`, `Age`) VALUES(@idSql,@NameSql,@AgeSql)", dbCon.Connection);
cmd.Parameters.AddWithValue("@idSql", getLastIdFromDB());
cmd.Parameters.AddWithValue("@NameSql", playerName.Text);
cmd.Parameters.AddWithValue("@AgeSql", playerAge.Text);
try
{
cmd.ExecuteNonQuery();
listView1.Items.Clear();
}
catch (Exception ex)
{
MessageBox.Show("Error:" + ex.Message);
dbCon.Connection.Close();
}
finally
{
updateListView();
}
}
}
对我来说,解决这个问题的最佳方式是什么,将来一定要正确关闭我的连接?
更新:(每个请求,包括DB_connect)
class DB_connect
{
private DB_connect()
{
}
private string databaseName = "simhopp";
public string DatabaseName
{
get { return databaseName; }
set { databaseName = value; }
}
public string Password { get; set; }
private MySqlConnection connection = null;
public MySqlConnection Connection
{
get { return connection; }
}
private static DB_connect _instance = null;
public static DB_connect Instance()
{
if (_instance == null)
_instance = new DB_connect();
return _instance;
}
public bool IsConnect()
{
bool result = true;
try
{
if (Connection == null)
{
if (String.IsNullOrEmpty(databaseName))
result = false;
string connstring = string.Format("Server=localhost; database={0}; UID=root;", databaseName);
connection = new MySqlConnection(connstring);
connection.Open();
result = true;
}
}
catch (Exception ex)
{
Console.Write("Error: " + ex.Message);
}
return result;
}
public void Close()
{
connection.Close();
}
}
}
答案 0 :(得分:2)
您正尝试在同一连接上安装多个打开的阅读器。这通常被称为" MARS" (多个活动结果集)。 MySql似乎不支持它。
您必须一次限制一个打开的阅读器,或使用多个连接,这样您就可以为每个阅读器建立一个连接。
我的建议是抛弃那些类似单身的东西,而是使用connection pooling和正确的using
块。
答案 1 :(得分:0)
这里的连接处理不好。你需要放弃DB_connect
。无需维护单个连接 - 只需在每次需要时打开和关闭连接。在幕后,ADO.NET将" pool"你的联系,所以你实际上不必等待重新连接。
对于任何实现IDisposable的对象,您需要在.Dispose()
块中调用finally
,或将其包装在using
语句中。这可确保您的资源得到妥善处理。我建议使用using
语句,因为它有助于保持范围清晰。
您的命名约定应符合C#标准。返回布尔值的方法应该类似于IsConnected
,而不是IsConnect
。 addPlayerBtn_Click
应为AddPlayerButton_Click
。 getLastIdFromDB
应为GetlastIdFromDb
或getLastIdFromDatabase
。
public string GetLastIdFromDatabase()
{
int lastIndex;
string lastID ="";
using (var connection = new MySqlConnection(Configuration.ConnectionString))
using (var command = new MySqlCommand("query", connection))
{
connection.Open();
MySqlDataReader reader = cmd2.ExecuteReader();
while (reader.Read())
{
string item = reader2["ID"].ToString();
lastIndex = int.Parse(item);
lastIndex++;
lastID = lastIndex.ToString();
}
}
return lastID;
}
注意,您的查询也很糟糕。我怀疑您使用字符串数据类型而不是数字,即使您的ID是基于数字的。您应该将列切换为数字数据类型,然后选择max()
数字。或使用自动增量列或序列来获取下一个ID。读取每一行以确定下一个ID并使计数器递增不好。