数据读取器会保持空值导致"Invalid attempt to call MetaData when reader is closed "吗?



我写了这个方法,这样我就不必每次都写打开连接等代码。

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

我认为这应该工作得很好,但最近我得到错误"无效尝试调用元数据时,阅读器关闭"。现在我不确定为什么会发生这个错误。但这似乎是最可能的原因。已经有一段时间了,所以我不能确定这个错误是否是由这种方式引起的。一旦使用块结束,数据读取器是否仍然为空?

using块结束后,数据读取器关闭。因此,任何从读取器读取数据的尝试都会抛出异常。请记住,数据读取器正在使用数据库连接。当连接关闭时(在using语句之后),将调用SQLConnection上的Dispose,从而使SqlDataReader为空。

把你的代码放在using语句之外,像这样。

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

因为您指定了:

CommandBehavior.CloseConnection

当您在关闭数据阅读器的那一刻执行命令对象时,与数据库的连接也将关闭。

如果你想让函数返回一个数据读取器而不是一个布尔值,你可以这样做。这取决于你的喜好。但是如果你返回一个数据阅读器,你可以用HasRowsRead方法检查。然后可以将数据读取器包装在using语句中,例如:

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

myDataReader的using语句结束时,将自动调用.Dispose()。由于您在GetMyDataReader()中使用CommandBehavior.CloseConnection调用.ExecuteReader(),那么处置读取器也将关闭您的数据库连接。

Read the post: ExecuteReader with CommanBehavior(读取数据后自动关闭连接)

你得到一个错误,因为你正在关闭连接时使用USING块。

而不是设置命令行为

  • CommandBehavior。CloseConnection

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

    1. 当你关闭阅读器时,不需要显式关闭连接。

      //不需要关闭连接,只需要写入reader.Close ();

    2. 在将reader传递给另一个方法处理数据时非常有用。

最新更新