2013-11-20 5 views
2

У меня есть код, как это в моей программе, и я считаю, что это не закрывает соединение после того, что данные наполняясь в.SqlDataAdapter метод Тесная связь

public static string ConnectionInfo = System.Configuration.ConfigurationManager.ConnectionStrings["Default"].ConnectionString; 
public static DataTable ExecuteQuery(string query, string table) 
    { 
     SqlConnection cnn = new SqlConnection(ConnectionInfo); 
     SqlDataAdapter Adp = new SqlDataAdapter(query, cnn); 
     DataSet Ds = new DataSet(); 
     Adp.Fill(Ds, table); 
     return Ds.Tables[table]; 
    } 

Есть ли какие-либо проблемы в этом коде?

+1

Вы фактически закрываете соединение где-нибудь? –

+0

'cnn.Close()' или 'using' ............? – Arran

+0

ссылается на эту ссылку

ответ

4

Единственная проблема заключается в том, что вы не используете using заявление для SqlConnection и DataAdapter. Однако DbDataAdapter.Fill открывает и закрывает соединение неявно.

public static DataTable ExecuteQuery(string query, string table) 
{ 
    using(SqlConnection cnn = new SqlConnection(ConnectionInfo)) 
    using(SqlDataAdapter Adp = new SqlDataAdapter(query, cnn)) 
    { 
     DataTable tbl = new DataTable(); 
     Adp.Fill(tbl); 
     return tbl; 
    } 
} 

Объект подключения, связанный с ЗЕЬЕСТОМ должен быть действительными, но он не должен быть открытым. Если соединение закрыто до вызова Fill, оно открывается для извлечения данных, затем закрывается. Если соединение открыто до вызова Fill, оно остается открытым.

Обратите внимание, что

  • using оператор закрывает соединение неявным даже в случае ошибки
  • я использовал DataAdapter.Fill(DataTable), потому что вы используете одну таблицу в любом случае

Редактировать : Я только что заметил, что вы используете параметр для имени таблицы. Вместо этого вы также можете использовать DbDataAdapter.Fill(DataSet, String). Это ничего не меняет.

+0

Я думаю, что вторая ' using' должно быть включено в скобки первого. –

+1

@AlbertoSolano: Нет, второе использование рассматривается как один оператор из-за фигурных скобок, поэтому он является частью первого использования (похоже на это 'if':' if (true) if (true) {;} ') , –

+0

А я понял, спасибо. Я никогда не пробовал этот подход. Я всегда использовал скобки даже для одной строки, для лучшей читаемости. :-) –

0

Добавить служебную инструкцию для надежного закрытия соединения. Это гарантирует, что соединение будет закрыто, даже если произойдет исключение. Измените код следующим образом:

public static DataTable ExecuteQuery(string query, string table) 
    { 
     using(SqlConnection cnn = new SqlConnection(ConnectionInfo)) 
     { 
      SqlDataAdapter Adp = new SqlDataAdapter(query, cnn); 
      DataSet Ds = new DataSet(); 
      Adp.Fill(Ds, table); 
      return Ds.Tables[table]; 
     } 
    } 
-1

Независимо от того, как открытие/закрытие соединений должно выполняться в блоке try-catch-finally.

И мы не должны использовать "с помощью" [с использованием (подключение SqlConnection = новый SqlConnection (ConnectionString))] блок. Потому что, если что-то пойдет не так с сетью или с какой-либо причиной исключения. Соединение: не работает. Так что лучше использовать блок try-catch.

public static DataTable ExecuteQuery(string query, string table) 
    { 
     DataSet Ds = new DataSet(); 

     SqlConnection cnn = new SqlConnection(ConnectionInfo); 

     try{ 
      SqlDataAdapter Adp = new SqlDataAdapter(query, cnn); 
      Adp.Fill(Ds, table); 
      return Ds.Tables[table]; 
     } 
     catch{ 
      throw; 
     } 
     finally{ 
      cnn.Close(); 
     } 

    } 
+1

_ «мы не должны использовать блок использования, потому что, если что-то пойдет не так с сетью или каким-либо исключением, соединение не будет закрыто». Это просто неправильно, 'SqlConnection.Dispose' будет называть' Close' неявно, даже по ошибке. Так что на самом деле простая инструкция 'using' будет переведена на ваш' try/finally'. –

Смежные вопросы