3

我有这个代码:

// this is managed elsewhere
SqlConnection connection =...
connection.Open();

// this is one block of code, separate from the above
using( var transaction = connection.BeginTransaction() ) {
   using( var command = connection.CreateCommand() ) {
     command.Transaction = transaction;
     command.CommandText = ...
     using( var reader = command.ExecuteReader() ) {
         if( reader.HasRows ) {
             if( reader.Read() ) {
                 //get data from the reader
             }
         }
     }
}

而且这段代码大部分时间都运行得很好。然而有时 - 很少 - 检索会HasRows产生以下异常:

Invalid attempt to call HasRows when reader is closed.
System.InvalidOperationException
  at System.Data.SqlClient.SqlDataReader.get_HasRows()
  // my code calling HasRows listed here

我有 99.5% 的把握在那一刻连接是打开的。我的代码HasRows在从读者那里阅读之前使用,就像 MSDN 建议的那样

该异常的原因可能是什么?

4

4 回答 4

4

这恰好是意外的行为ExecuteReader()- 很可能是一个错误。内部深处ExecuteReader()发生了一些随机错误,很可能是网络超时,连接关闭,然后SqlDataReader返回关闭,就好像什么都没发生一样。难怪后续调用会HasRows产生异常。

于 2013-01-10T10:00:27.267 回答
2

quickfix 您可以添加一个检查以查看您的连接是否在 hasrows 之前打开,如果连接已关闭,请再次打开您的连接

但我建议您也在那里添加体面的日志记录(我很好奇;))

于 2012-12-20T10:16:56.270 回答
1

我担心您在上面的评论,即您不是每次都创建连接。让连接池担心开销。您应该每次都创建一个连接。创建连接,进行读取,销毁连接。长期存在的连接可能会在服务器之间丢弃通信时出现间歇性问题(所需要的只是超时或一些丢弃的数据包)。

于 2012-12-20T11:34:35.267 回答
0

你有没有在任何地方声明你的 DataReader????

此外,如果您有 BeginTransaction() 函数,那么该函数应该具有您想要执行的命令类型的功能,即 executeReader、ExecuteNonQuery 等。首先检查您的阅读器:

ISReading...

然后继续使用 reader.hasRow。

DataReader 还存储一个完整的表,所以你应该检查 Tables[0].rows

于 2012-12-20T09:03:51.353 回答