这让我头疼。我知道这个问题(或者至少是它的变体)已经问过很多次了,但是在一个标记为重复之前,请考虑以下代码:
string myConnectionString = myConnectionString = ConfigurationManager.ConnectionStrings["DBCS"].ToString();
SqlConnection mySQLConnection;
SqlCommand mySQLCommand;
SqlDataReader mySQLDataReader;
using (mySQLConnection = new SqlConnection(myConnectionString))
{
mySQLCommand = new SqlCommand("SELECT TOP 1 * FROM Table ORDER BY Id DESC", mySQLConnection);
mySQLCommand.Connection = mySQLConnection;
mySQLCommand.Connection.Open();
using(mySQLDataReader = mySQLCommand.ExecuteReader())
{
if (mySQLDataReader.HasRows)
{
if (mySQLConnection.State == ConnectionState.Open)
{
while (mySQLDataReader.Read())
{
//Perform Logic : If the last record being returned meets some condition then call the below method
MethodCalled();
}
}
}
}
MessageBox.Show("Connection state: " + mySQLConnection.State);
}
我想找一种方法:
while-loop
已完成读取,并且不再有行时,它将退出但我只是不断地得到一个SqlException
,说明如下:
关闭读取器时调用读的尝试无效
从广泛的观察来看,我可以跟踪错误是因为我返回了只包含一行的数据。问题是,在读取了该行之后,编译器返回到While(mySQLDataReader.Read()){}
,并尝试读取不包含任何行的表。
我尝试了以下几点:
ExecuteReader()
从using
块中的命令对象中包装,这样一旦读取完成如下操作,它就会自动关闭读取器和连接:
使用(mySQLDataReader= mySQLCommand.ExecuteReader()) {//逻辑执行}while-loop
的结束大括号之前,我试着检查是否还有更多的行从sql命令中留下/返回,并在满足该条件后退出循环:
如果(mySQLDataReader.HasRows == false) //没有更多行要读取{==;//中断循环}两次尝试都没有成功。我怎么才能避开这一切?
发布于 2017-09-05 01:15:48
它必须是以下三件事之一:
Read()
块之外使用using
。请记住,using
块将隐式调用阅读器上的Close
和Dispose
。因此,任何Read()
调用都必须放在using
块中。using
块的主体是显式关闭读取器。这似乎不太可能。mySQLDataReader
在一个更高的水平。可能是其他一些(异步)代码关闭了读取器。这也不太可能。在大多数情况下,您不应该在全局级别定义DataReader
。编辑
阅读您现在发布的完整代码块,我建议进行一些修改。您能不能运行以下命令并告诉我们它是否运行:
using (var mySQLConnection = new SqlConnection(myConnectionString))
{
mySQLCommand = new SqlCommand("SELECT TOP 1 * FROM Table ORDER BY Id DESC", mySQLConnection, mySQLConnection);
mySQLCommand.Connection.Open();
using(mySQLDataReader = mySQLCommand.ExecuteReader())
{
while (mySQLDataReader.Read())
{
//Perform Logic : If the last record being returned meets some condition then call the below method
MethodCalled();
}
}
}
如果这个版本运行良好,那么我们可以更好地挖掘这个问题。
发布于 2017-09-05 01:54:47
如果没有要迭代的数据,则while循环将完全不执行。您需要检查HasRows本身吗?此外,在创建数据读取器时应使用CommandBehavior.CloseConnection。这将确保一旦您阅读了底层连接,就会关闭它。
如果我打电话给SqlDataReader.HasRows,应该打给SqlReader.Read吗?
using (SqlConnection mySQLConnection = new SqlConnection(myConnectionString))
{
using (SqlCommand mySQLCommand = new SqlCommand("SELECT TOP 1 * FROM Table ORDER BY Id DESC", mySQLConnection))
{
mySQLConnection.Open();
SqlDataReader mySQLDataReader = mySQLCommand.ExecuteReader(CommandBehavior.CloseConnection);
while (mySQLDataReader.Read())
{
//Code logic here
}
// this call to mySQLDataReader.Close(); will close the underlying connection
mySQLDataReader.Close();
}
MessageBox.Show("Connection state: " + mySQLConnection.State);
}
https://stackoverflow.com/questions/46051038
复制