【问题标题】:There is already an open DataReader associated with this Connection which must be closed first已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭
【发布时间】:2011-04-02 15:00:59
【问题描述】:
我正在使用带有 mysqlConnector 的 Visual Studio 2010 (C#),一切似乎都很好。
但是,当我尝试从服务器请求某些内容时,我收到此错误:
“已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭它。”
这是我的代码:
gc.connect();
List<Conseiller> conseillers = gc.getAllConseillers();
--
public void connect()
{
string connStr = "SERVER=localhost;UID=root;DATABASE=Projet;Password=root";
oConn = new MySqlConnection(connStr);
try
{
oConn.Open();
Console.WriteLine("Successfully connected to the data base");
}
catch (OdbcException caugth)
{
/* Traitement de l'erreur */
Console.WriteLine(caugth.Message);
}
}
--
public List<Conseiller> getAllConseillers()
{
MySqlCommand oComm = oConn.CreateCommand();
oComm = oConn.CreateCommand();
Console.WriteLine("SELECT * FROM conseillers");
oComm.CommandText = "SELECT * FROM conseillers";
MySqlDataReader oReader = oComm.ExecuteReader(); // Error here
}
我哪里错了?
【问题讨论】:
标签:
c#
.net
mysql
database
visual-studio
【解决方案1】:
不要尝试将连接与获取数据分开。对 Open 的调用实际上可能根本不会进入数据库,此时您将不会检测到问题。注意用于关闭连接的 using 语句。根据需要添加 SEH
List<Conseiller> conseillers = gc.getAllConseillers();
public void getAll() {
string connStr = "SERVER=localhost;UID=root;DATABASE=Projet;Password=root";
using (oConn = new MySqlConnection(connStr))
using (MySqlCommand oComm = oConn.CreateCommand())
{
oConn.Open();
oComm.CommandText = "SELECT * FROM conseillers";
MySqlDataReader oReader = oComm.ExecuteReader(); // no Error here
// user reader here
} catch (OdbcException caugth) {
/* Traitement de l'erreur */
Console.WriteLine(caugth.Message);
}
}
【解决方案2】:
您没有处理您的对象,这基本上意味着您之前对 getAllConseillers 或类似方法的调用打开了一个仍处于打开状态的数据读取器。
您问题中的以下对象是一次性的(即实现IDisposable),您应该将它们全部丢弃:
- MySqlConnection
- MySqlCommand
- MySqlDataReader
基本上,我会将代码更改为如下所示:
using (var gc = new Whatever())
{
gc.connect();
List<Conseiller> conseillers = gc.getAllConseillers();
}
--
public void connect()
{
string connStr = "SERVER=localhost;UID=root;DATABASE=Projet;Password=root";
oConn = new MySqlConnection(connStr);
try
{
oConn.Open();
Console.WriteLine("Successfully connected to the data base");
}
catch (OdbcException ex)
{
/* Traitement de l'erreur */
Console.WriteLine(ex.Message);
oConn.Dispose();
oConn = null;
// optional: throw;
}
}
--
public List<Conseiller> getAllConseillers()
{
using (MySqlCommand oComm = oConn.CreateCommand())
{
Console.WriteLine("SELECT * FROM conseillers");
oComm.CommandText = "SELECT * FROM conseillers";
using (MySqlDataReader oReader = oComm.ExecuteReader()) // No error here
{
// process the result in oReader here
return ...;
}
...
}
...
}
【解决方案3】:
一些可能有帮助的建议:
首先,在您上面的代码中,您已经调用了两次 CreateCommand 并且不需要。
其次,您可以将您的 Command 实例化一点,以使其更易于阅读:
MySqlCommand oComm = new MySqlCommand("Select * from conseillers", oConn);
然后调用 ExecuteReader。
第三,您上面的代码在连接打开时不会显示。你确定它是开放的?您确定您还没有通过打开的连接调用数据读取器并且没有关闭它吗?
第四,您应该始终尽可能晚地打开连接并尽可能早地关闭它。您拥有的代码似乎要打开连接并使其保持打开状态,但我不确定您的意图。
我建议使用 Using 语法:
Using connection As New SqlConnection(connectionString)
Dim command As New SqlCommand(queryString, connection)
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
Try
While reader.Read()
Console.WriteLine(String.Format("{0}, {1}", _
reader(0), reader(1)))
End While
Finally
' Always call Close when done reading.
reader.Close()
End Try
End Using
根据你的情况修改上面的代码....