2010-03-18 6 views
16

Ich verwende ADO.NET (.NET 1.1) in einer Legacy-App. Ich weiß, dass DataAdapter.Fill() Verbindungen öffnet und schließt, wenn die Verbindung nicht manuell geöffnet wurde, bevor sie an den DataAdapter übergeben wird.Schließt DataAdapter.Fill() die Verbindung, wenn eine Ausnahme ausgelöst wird?

Meine Frage: Schließt es auch die Verbindung, wenn die .Fill() eine Ausnahme verursacht? (aufgrund von SQL Server kann nicht erreicht werden, oder was auch immer). Verliert es eine Verbindung oder verfügt es über eine integrierte Schlussklausel, um sicherzustellen, dass die Verbindung geschlossen wird?

Codebeispiel:

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

Ohne es genau zu wissen, würde ich davon ausgehen, dass es aber tut. Sie können jedoch Reflector (http://www.red-gate.com/products/reflector/) verwenden, um in die Implementierung zu schauen und zu sehen, ob sie letztendlich implementiert. – AxelEckenberger

Antwort

20

Wenn die Verbindung geöffnet ist, bevor das Fill() -Methode aufgerufen wird, dann nicht, die Verbindung wird nicht durch die Dataadapter geschlossen werden.

Wenn Sie jedoch die Verbindung nicht explizit öffnen und stattdessen den DataAdapter innerhalb des Befehls Fill() öffnen und schließen, wird die Verbindung bei einem Fehler geschlossen.

Dies kann aus mehreren Quellen der Dokumentation impliziert werden, einschließlich dieser: Data Access Strategies Using ADO.NET and SQL

Ferner kann diese durch das Schreiben einer Routine im Code gezeigt werden, dass Fehler anzeigt und dann die staatliche Verbindung zu überprüfen.

Dieser Code aus einer Windows Forms App beweist es. Das erste Nachrichtenfeld wird "Öffnen" und das zweite "Geschlossen" sagen.

   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

Großartig, danke für dieses Beispiel! – motto

1

Es nicht die Verbindung schließen. Dieses Beispiel funktioniert und gibt die Id von "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(); 

Edit:

Wenn Sie die Verbindung vor der Hand öffnen (Open auf dem IDbConnection Objekt aufgerufen wird), die IDataAdapter schließt es nicht. Wenn Sie dem IDataAdapter jedoch erlauben, die Verbindung vollständig zu verwalten, wird sie geschlossen.

+0

Ja, wenn Sie es öffnen, sind Sie dafür verantwortlich, es selbst zu schließen. Ich betrachte jedoch eine Situation, in der DataAdapter die Verbindung für mich öffnet. – motto

+0

In diesem Fall wird es vom DataAdapter geschlossen. – scottm

+0

aber dann, wenn Sie zulassen, dass der DataAdapter den Abschluss behandelt, dann wird der Insert-Befehl funktionieren? Ich stimme zu, dass die Auswahl und die Füllung funktionieren. – variable