2010-03-18 36 views
16

Estoy usando ADO.NET (.NET 1.1) en una aplicación heredada. Sé que DataAdapter.Fill() abre y cierra las conexiones si la conexión no se ha abierto manualmente antes de que se le dé al DataAdapter.¿DataAdapter.Fill() cierra su conexión cuando se lanza una excepción?

Mi pregunta es: ¿También cierra la conexión si el .Fill() causa una excepción? (debido a SQL Server no se puede alcanzar, o lo que sea). ¿Se filtró una conexión o tiene una cláusula Finally incorporada para asegurarse de que la conexión se cierre?

Código Ejemplo:

Dim cmd As New SqlCommand 
Dim da As New SqlDataAdapter 
Dim ds As New DataSet 
cmd.Connection = New SqlConnection(strConnection) 
cmd.CommandText = strSQL 
da.SelectCommand = cmd 
da.Fill(ds) 
+1

Sin saberlo exactamente, supongo que sí. Sin embargo, puede usar Reflector (http://www.red-gate.com/products/reflector/) para examinar la implementación y ver si implementa finalmente. – AxelEckenberger

Respuesta

20

Si la conexión está abierta antes de llamar al método Fill(), entonces no, la conexión no se cerrará por el adaptador de datos.

Sin embargo, si no abre explícitamente la conexión, y en su lugar deja que el DataAdapter abra y cierre la conexión dentro del comando Fill(), la conexión se cerrará en caso de error.

Esto puede deducirse de varias fuentes de documentación, incluyendo éste: Data Access Strategies Using ADO.NET and SQL

Además, esto puede ser demostrado en el código escribiendo una rutina que el error fuera y luego la comprobación del estado de la conexión.

Este código de una aplicación de Windows Forms lo demuestra. El primer cuadro de mensaje dirá "Abrir" y el segundo "Cerrado".

   string connString = ""; 
     private void Form1_Load(object sender, EventArgs e) 
     { 
      connString = Properties.Settings.Default.EventLoggingConnectionString; 
      ExplicitlyOpenConnection(); 
      LetDataAdapterHandleIt(); 
     } 

     private void ExplicitlyOpenConnection() 
     { 
      System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(connString); 
      System.Data.DataSet ds = new DataSet(); 
      System.Data.SqlClient.SqlDataAdapter ad = new System.Data.SqlClient.SqlDataAdapter("Select bogusdata from nonexistenttable", cn); 

      cn.Open(); 
      try 
      { 
       ad.Fill(ds); 
      } 
      catch (Exception ex) 
      { 

      } 

      MessageBox.Show(cn.State.ToString()); 
      cn.Close(); 
     } 
     private void LetDataAdapterHandleIt() 
     { 
      System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(connString); 
      System.Data.DataSet ds = new DataSet(); 
      System.Data.SqlClient.SqlDataAdapter ad = new System.Data.SqlClient.SqlDataAdapter("Select bogusdata from nonexistenttable", cn); 

      try 
      { 
       ad.Fill(ds); 
      } 
      catch (Exception ex) 
      { 

      } 
      MessageBox.Show(cn.State.ToString()); 
     } 
+0

Genial, gracias por este ejemplo! – motto

1

Se no cerrar la conexión. Este ejemplo funciona y da salida a la identificación de "ARealTable"

  using (SqlConnection conn = new SqlConnection("Data Source=server;Initial Catalog=database;user id=sa; password=password;")) 
      { 
       conn.Open(); 

       try 
       { 
        SqlDataAdapter adap = new SqlDataAdapter("SELECT * FROM NotATable", conn); 
        /* Exception thrown next */ 
        adap.Fill(new DataSet("test")); 
       } 
       catch (Exception) { } 

       using (SqlCommand cmd = new SqlCommand("SELECT TOP 1 Id FROM ARealTable", conn)) 
       { 
        string result = Convert.ToString(cmd.ExecuteScalar()); 
        Console.WriteLine(result); 
       } 
       Console.ReadKey(); 

Editar:

Si abre la conexión antes de mano (llamando abierta sobre el objeto IDbConnection), el IDataAdapter no cerrarla. Sin embargo, si permite que IDataAdapter administre la conexión por completo, se cerrará.

+0

Sí, si lo está abriendo, usted es responsable de cerrarlo usted mismo. Sin embargo, estoy viendo una situación en la que DataAdapter abre la conexión por mí. – motto

+0

En ese caso, será cerrado por el DataAdapter. – scottm

+0

pero luego, si permite que el datadapter maneje el cierre, ¿funcionará el comando insert? Acepto que la selección y el relleno funcionarán. – variable

Cuestiones relacionadas