2011-03-26 11 views
19

tengo debajo de código y me estoy haciendo una excepción:Excepción: Ya hay un DataReader abierto asociado con esta conexión que debe estar cerrada primera

Ya hay un proceso abierto DataReader asociada a este Connection que debe estar cerrada primero.

Estoy usando Visual Studio 2010/.Net 4.0 y MySQL para este proyecto. Básicamente, estoy tratando de ejecutar otra declaración SQL mientras uso el lector de datos para hacer mi otra tarea. Me estoy haciendo una excepción en la línea 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." 
     } 
    } 
} 
+0

El mensaje de error que veo es '... asociada a este comando ** ** ...', supongo que el mensaje es un error y este post explica que –

Respuesta

31

Está utilizando la misma conexión para el DataReader y el ExecuteNonQuery. Esto no es compatible, according to MSDN:

Tenga en cuenta que mientras que un DataReader está abierta, la conexión está en uso exclusivamente por que DataReader. No puede ejecutar ningún comando para Connection, incluida la creación de otro DataReader, hasta que se cierre el DataReader original .

20

Siempre, siempre, siempre coloque objetos desechables en el interior de la utilización de declaraciones. No puedo ver cómo se haya creado una instancia su DataReader pero debe hacerlo de esta manera:

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

Ahora, para responder a su pregunta, el lector está utilizando la misma conexión que el comando que está tratando de ExecuteNonQuery en. Debe usar una conexión separada ya que el DataReader mantiene la conexión abierta y lee los datos como los necesite.

+0

Niza con el balón! ;-) Bien por usted. La segunda parte no estaba allí mientras escribía el comentario. Lo siento. – David

+0

Sí, aprieto para guardarlo prematuramente, debe haber visto mi respuesta durante esa ventana de 3 segundos. –

+0

Gracias .. He creado otra conexión para manejar mi problema .... Gracias .... –

9

Se está intentando a una inserción (con ExecuteNonQuery()) en una conexión de SQL que se utiliza por este lector ya:

while (myReader.Read()) 

Cualquiera de leer todos los valores en una lista en primer lugar, cerrar el lector y luego hacer la inserción, o use una nueva conexión SQL.

+0

Eso es lo que iba a poner, pero estaba muy ocupado comentando a continuación. Maldita sea. De todos modos, sí, esa es la respuesta: use un objeto de conexión diferente. +1 a ti. – David

1

El problema que se está ejecutando es que está iniciando un segundo MySqlCommand mientras sigue leyendo datos con el DataReader. El conector MySQL solo permite una consulta simultánea. Necesita leer los datos en una estructura, cerrar el lector y luego procesar los datos. Lamentablemente, no puede procesar los datos tal como se leen si su procesamiento implica más consultas SQL.

-1

Según lo declarado por David Suárez, está tratando de leer en paralelo. Tuve el mismo problema y encontré una solución rápida y fácil.

Antes de comenzar su lectura hacer un bucle de espera

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

A continuación, antes de empezar su SqlCommand llamar a la función anterior. Algo así como:

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

Este código no funciona. [El estado de conexión de obtención no está implementado] (http://stackoverflow.com/a/15339392/1111886). También en su ejemplo secundario de cómo usar el método, en realidad nunca llama al método. – Fr33dan

+0

Estoy usando .Net 4.6.1 y está funcionando. –

+0

¿Qué conector estás usando? Todavía estoy usando .NET 3.5 pero usando la última versión del conector MySQL (6.9.9). El evento fue y descargué el [código fuente] (https://dev.mysql.com/downloads/connector/net/) para él y no puedo encontrar ningún rastro de 'ConnectionState.Fetching' en el archivo fuente MySqlConnection. El código funciona para una sola lectura, pero la segunda lectura simultánea todavía da el error. – Fr33dan

Cuestiones relacionadas