2010-08-23 71 views
13

ExecuteNonQuery requiere una conexión abierta y disponible. El estado actual de la conexión está cerrado.ExecuteNonQuery requiere una conexión abierta y disponible. El estado actual de la conexión está cerrado

¿Qué estoy haciendo mal aquí? Supongo que puedes reutilizar la conexión.

¡Gracias por cualquier ayuda!

using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString())) 
{ 
    cn.Open(); 

    // If we are reverting to an old type 
    if (pageAction == "revert") 
    { 
     debug.Text = "FLAG 1"; 

     // Get the revert ID 
     int revertingID = int.Parse(Request.QueryString["revID"]); 
     bool rowsReturned = false; 

     debug.Text = "FLAG 2 - " + revertingID.ToString(); 

     // Set all to 0 
     using (SqlCommand cmd = new SqlCommand("SELECT ID FROM tblSiteSettings WHERE ID = " + revertingID, cn)) 
     { 
      // If it exists 
      SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); 
      if (rdr.Read()) 
      { 
       rowsReturned = true; 
      } 
      rdr.Close(); 
     } 

     debug.Text = "FLAG 3 - " + rowsReturned.ToString(); 

     // Set new active and reset others 
     if (rowsReturned == true) 
     { 
      using (SqlCommand cmd = new SqlCommand("UPDATE tblSiteSettings SET isActive = 1 WHERE ID = " + revertingID, cn)) 
      { 
       cmd.ExecuteNonQuery(); 
      } 
      using (SqlCommand cmd = new SqlCommand("UPDATE tblSiteSettings SET isActive = 0 WHERE ID <> " + revertingID, cn)) 
      { 
       cmd.ExecuteNonQuery(); 
      } 
     } 
     //debug.Text = "FLAG 4 - "; 
    } 

Respuesta

16

Su problema es:

SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); 

Usted sólo debe llamar cmd.ExecuteReader()' si desea utilizar la conexión de nuevo antes de "desembarazarse "de eso. Si quiere entender lo que hace/significa la parte CommandBehaviour.CloseConnection, la documentación para SqlCommand.ExecuteReader es una buena opción. También hay documentación para decirle cuáles son todos los valores posibles de CommandBehaviour enumeration. Básicamente CommandBehaviour.CloseConnection hace lo siguiente:

Cuando se ejecuta el comando, el objeto de conexión asociado se cierra cuando se cierra el objeto DataReader asociado.

Si usted no tiene ninguna necesidad especial para especificar un CommandBehaviour, a continuación, especificar CommandBehaviour.Default, o no se especifica ninguno en absoluto. CommandBehaviour.Default es:

La consulta puede devolver varios conjuntos de resultados. La ejecución de la consulta puede afectar el estado de la base de datos. El valor predeterminado no establece indicadores CommandBehavior, por lo que llamar a ExecuteReader (CommandBehavior.Default) es funcionalmente equivalente a llamar a ExecuteReader().

+0

¿La instrucción Using() sus comandos están envueltos en cerrar la conexión cuando descarta el SqlCommand? – Tommy

+0

@Tommy, no tan lejos como yo sepa, la documentación para SqlCommand.Dispose no la menciona, así que supongo que no (http://msdn.microsoft.com/en-us/library/system .data.sqlclient.sqlcommand.dispose.aspx) – Rob

+0

Buena llamada, si la definición de conexión se envolvió en un bloque Using, entonces lo haría. http://stackoverflow.com/questions/410222/does-connection-close-when-command-is-disposed-and-the-connection-is-defined-dire – Tommy

5

Usted está cerrando la conexión rdr.Close(); y nunca volver a abrirlo antes de llamar ExecuteNonQuery().

En realidad, no necesita cerrarlo en absoluto si está envuelto en un using ya que la llamada al Dispose() cerrará automáticamente la conexión.

4

Parece que está haciendo una lectura antes de ejecutar su ExecuteNonQuery. En su primera llamada a SqlCommand (para SELECT), está cerrando la conexión después de que se complete la lectura.

SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); 

Elimine el comportamiento del comando, debe estar listo para continuar o vuelva a abrir la conexión en su siguiente instrucción if.

Este

SqlDataReader rdr = cmd.ExecuteReader(); 

O esto

if (rowsReturned == true){ 
    cn.open(); 
1

Aquí, el SqlDataReader se cerrará la conexión cuando se complete:

// Set all to 0 
using (SqlCommand cmd = new SqlCommand("SELECT ID FROM tblSiteSettings WHERE ID = " + revertingID, cn)) 
{ 
    // If it exists 
    SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); 
    if (rdr.Read()) 
    { 
     rowsReturned = true; 
    } 
    rdr.Close(); 
} 

Más adelante, el "Establecer nueva activa y restablece los demás" sección fallará, ya que la conexión está cerrada.

2

Simplemente agregue cn.Open antes, o no lo cierre.

Cuestiones relacionadas