2011-04-07 33 views
1

我寫了這個方法,這樣我就不必每次都寫開放連接等代碼。dataReader是否會保持null,導致「讀取器關閉時調用MetaData的嘗試失敗」?

public static bool TryExecuteReader(string commandText,string functionNameForLogging, string errorText, out SqlDataReader dataReader) 
     { 
      bool success = false; 
      dataReader = null; 
      try 
      { 
       using (SqlConnection sqlConnection = SqlUtilities.CreateSqlConnection()) 
       { 
        sqlConnection.Open(); 
        SqlCommand sqlCommand = sqlConnection.CreateCommand(); 
        sqlCommand.CommandText = commandText; 
        dataReader = sqlCommand.ExecuteReader(CommandBehavior.CloseConnection);      
       } 
       success = true; 
      } 
      catch (Exception ex) 
      { 
       SqlUtilities.LogError(functionNameForLogging,ex.Message,-1); 
      } 

      return success; 
     } 

我認爲這應該可以正常工作,但最近我收到錯誤「無效的嘗試調用元數據,當閱讀器關閉」。現在我不確定爲什麼會出現這個錯誤。但這似乎是最可能的原因。它已經有一段時間了,所以我無法確定錯誤是否是由這種方式引起的。數據讀取器在使用塊結束後是否保留爲空?

回答

1

一旦使用塊結束,datareader關閉。 因此,任何從讀取器讀取數據的嘗試都會引發異常。 記住datareader正在使用db連接。當連接關閉時(在使用語句之後)將依次調用SQLConnection上的Dispose,從而使SqlDataReader無/ null。

把你的代碼放在using語句之外,如下所示。

SqlConnection sqlConnection = SqlUtilities.CreateSqlConnection() 
using(SqlCommand sqlCommand = sqlConnection.CreateCommand()) 
{ 
    sqlCommand.CommandText = commandText; 
    dataReader = sqlCommand.ExecuteReader (CommandBehavior.CloseConnection);      
} 
conn.Open(); 
success=true; 

因爲你已經指定:

CommandBehavior.CloseConnection

當你執行你的命令對象,你閉上你的數據讀取分鐘到數據庫的連接也將被關閉。

如果你想讓你的函數返回一個datareader而不是一個布爾值,你可以。這真的取決於你的喜好。但是,如果您返回一個數據讀取器,您可以使用HasRowsRead方法進行檢查。然後,您可以在包裝中的DataReader using語句,例如:

using (SqlDataReader myDataReader = GetMyDataReader()) 
{ 
    //do something with the reader 
} 

在using語句myDataReader.Dispose()年底將被自動調用。由於您在GetMyDataReader()中調用.ExecuteReader()CommandBehavior.CloseConnection,那麼處置讀取器也會關閉您的db連接。

+0

但DataReader的被宣佈爲使用外塊。而是在外部宣佈並傳遞給此方法。 – shashi 2011-04-07 13:03:11

+0

@sassyboy - 這並不重要,因爲您正在命令對象中使用連接sqlConnection。並且使用你的sqlConnection對象的命令對象被用於'.ExecuteReader'。這意味着你的數據庫正在使用你的sqlConnection對象。因此,在sqlConnection對象被使用的using語句之後立即發生了什麼,這意味着您的命令對象已完成並且您的數據讀取器已完成。 – JonH 2011-04-07 13:06:13

1

閱讀帖子:ExecuteReader with CommanBehavior (automatically close connection after reading data)

由於你使用的是USING塊時關閉連接得到一個錯誤。

取而代之的是一套命令行爲

  • CommandBehavior.CloseConnection

    當您通過上面的值作爲參數的ExecuteReader

    1. 沒有必要明確地關閉連接當你關閉你的閱讀器時連接就會關閉。

      //無需關閉連接,只需寫入 reader.Close();

    2. 當您將閱讀器傳遞給另一種處理數據的方法時,它會很有用。

相關問題