例外:已经有一个打开的DataReader与这个Connection关联,必须先closures它

我有下面的代码,我得到exception:

已经有一个打开的DataReader与这个Connection关联,必须先closures它。

我为这个项目使用Visual Studio 2010 / .Net 4.0和MySQL。 基本上我试图运行另一个SQL语句,而使用数据读取器来做我的其他任务。 我在行cmdInserttblProductFrance.ExecuteNonQuery();

 SQL = "Select * from tblProduct"; //Create Connection/Command/MySQLDataReader MySqlConnection myConnection = new MySqlConnection(cf.GetConnectionString()); myConnection.Open(); MySqlCommand myCommand = new MySqlCommand(SQL, myConnection); MySqlDataReader myReader = myCommand.ExecuteReader(); myCommand.Dispose(); if (myReader.HasRows) { int i = 0; // Always call Read before accessing data. while (myReader.Read()) { if (myReader["frProductid"].ToString() == "") //there is no productid exist for this item { strInsertSQL = "Insert Into tblProduct_temp (Productid) Values('this istest') "; MySqlCommand cmdInserttblProductFrance = new MySqlCommand(strInsertSQL, myConnection); cmdInserttblProductFrance.ExecuteNonQuery(); //<=====THIS LINE THROWS "C# mySQL There is already an open DataReader associated with this Connection which must be closed first." } } } 

您正在使用DataReaderExecuteNonQuery相同的连接。 根据MSDN的说法,这不被支持:

请注意,在DataReader打开的情况下,连接将由该DataReader独占使用。 您不能为Connection执行任何命令,包括创build另一个DataReader,直到closures原始DataReader。

总是,总是把可丢弃的对象放在使用语句中。 我看不到你是如何实例化你的DataReader,但你应该这样做:

 using (Connection c = ...) { using (DataReader dr = ...) { //Work with dr in here. } } //Now the connection and reader have been closed and disposed. 

现在,为了回答你的问题,读者正在使用与你正在尝试ExecuteNonQuery的命令相同的连接。 您需要使用单独的连接,因为DataReader会保持连接打开并根据需要读取数据。

您正尝试在此读取器使用的SQL连接上使用Insert(使用ExecuteNonQuery() ):

 while (myReader.Read()) 

要么先读取列表中的所有值,closures读取器,然后执行插入,或使用新的SQL连接。

您遇到的问题是您正在启动第二个MySqlCommand同时仍然使用DataReader读回数据。 MySQL连接器只允许一个并发查询。 您需要将数据读入某个结构,然后closures读取器,然后处理数据。 不幸的是,如果你的处理涉及到更多的SQL查询,你将无法处理数据。

正如大卫·苏亚雷斯(David Suarez)所说,你正试图平行地阅读。 我有同样的问题,并find了一个快速和简单的解决scheme。

在开始阅读之前,先做一个等待循环

 private void WaitForEndOfRead() { int count = 0; while (_connection.State == ConnectionState.Fetching) { Thread.Sleep(1000); count++; if (count == 10) { break; } } } 

然后在你启动你的SqlCommand之前调用上面的函数。 就像是:

 using (SqlCommand command = new SqlCommand("GetData", _connection)) { command.CommandType = CommandType.StoredProcedure; using (SqlDataReader dr = command.ExecuteReader()) { // do your thing here } }