web-dev-qa-db-fra.com

Exception: il existe déjà un DataReader ouvert associé à cette connexion qui doit être fermé en premier

J'ai le code ci-dessous et je reçois une exception:

Il existe déjà une DataReader ouverte associée à cette Connection qui doit être fermée en premier.

J'utilise Visual Studio 2010/.Net 4.0 et MySQL pour ce projet. Fondamentalement, j'essaie d'exécuter une autre instruction SQL lorsque j'utilise un lecteur de données pour effectuer mon autre tâche. Je reçois une exception à la ligne 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."
        }
    }
}
23
Lord OfTheRing

Vous utilisez la même connexion pour la DataReader et la ExecuteNonQuery. Ceci n'est pas supporté, selon MSDN :

Notez que lorsqu'un DataReader est ouvert, la connexion est en cours d'utilisation exclusivement par ce DataReader. Vous ne pouvez exécuter aucune commande pour la connexion, y compris la création d'un autre DataReader, jusqu'à ce que le DataReader d'origine est fermé.

Mise à jour 2018: lien vers MSDN

38
David Suarez

Toujours, toujours, toujours mettre des objets jetables à l'intérieur des instructions using. Je ne vois pas comment vous avez instancié votre DataReader, mais vous devriez le faire comme ceci:

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

Maintenant, pour répondre à votre question, le lecteur utilise la même connexion que la commande que vous essayez d'utiliser ExecuteNonQuery on. Vous devez utiliser une connexion distincte car DataReader maintient la connexion ouverte et lit les données selon vos besoins.

25
Josh M.

Vous essayez d’insérer (avec ExecuteNonQuery()) sur une connexion SQL déjà utilisée par ce lecteur:

while (myReader.Read())

Lisez d'abord toutes les valeurs d'une liste, fermez le lecteur puis effectuez l'insertion ou utilisez une nouvelle connexion SQL.

9
BrokenGlass

Le problème que vous rencontrez est que vous démarrez une deuxième MySqlCommand tout en lisant les données avec la DataReader. Le connecteur MySQL n'autorise qu'une requête simultanée. Vous devez lire les données dans une structure, puis fermer le lecteur, puis traiter les données. Malheureusement, vous ne pouvez pas traiter les données telles qu'elles sont lues si votre traitement implique d'autres requêtes SQL.

1
Matthew Scharley

Vous devez fermer le lecteur par-dessus votre autre condition.

0
Sergej Kembel