dataReader是否仍然为null,导致“读取器关闭时无效尝试调用MetaData”?

时间:2011-04-07 12:32:24

标签: asp.net data-access-layer

我写了这个方法,所以我不必每次都写开放连接等代码。

 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;
        }

我认为这应该可以正常工作,但最近我收到错误“读取器关闭时无效尝试调用MetaData”。现在我不确定为什么会出现这个错误。但这似乎是最可能的原因。已经有一段时间了,所以我无法确定错误是否是由这种方式引起的。一旦使用块结束,datareader是否保持为空?

2 个答案:

答案 0 :(得分:1)

使用块结束后,datareader将关闭。 因此,任何从读取器读取数据的尝试都会引发异常。 请记住,datareader正在使用数据库连接。当连接关闭时(在您的using语句之后)将在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而不是boolean,你可以。这真的取决于你的偏好。但是,如果您返回datareader,则可以使用HasRowsRead方法进行检查。然后,您可以将datareader包装在using语句中,例如:

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

myDataReader .Dispose()的using语句结束时将自动调用。由于您使用.ExecuteReader()GetMyDataReader()内部调用CommandBehavior.CloseConnection,因此处理读取器也会关闭数据库连接。

答案 1 :(得分:1)

阅读帖子:ExecuteReader with CommanBehavior ( automatically close connection after reading data)

您收到错误是因为在使用USING块时关闭了连接。

而不是这个设置命令行为

  • <强> CommandBehavior.CloseConnection

    将上述值作为参数传递给ExecuteReader

    1. 关闭阅读器时无需关闭连接显式连接。

      //无需关闭连接,只需编写即可 reader.Close();

    2. 将读者传递给另一种处理数据的方法时非常有用。