C#中数据库连接时Reader异常:关闭后无法读取

需积分: 50 1 下载量 38 浏览量 更新于2024-12-03 收藏 2KB TXT 举报
在C#编程中,当试图在数据库读取器(SqlDataReader)关闭后执行`Read()`操作时,可能会出现"Reader is closed"或"Reading from a closed reader"这样的错误提示。这通常发生在代码中尝试访问已经关闭的`SqlDataReader`对象,例如在`setValue`方法中。让我们深入分析这两个方法以及引发错误的原因。 首先,来看`GetSqlDataReader`方法: ```csharp public override SqlDataReader GetSqlDataReader(string Sql, SqlParameter[] commandParameters) { SqlDataReader sdr = null; using (SqlConnection connection = GetSqlConnection()) { SqlCommand command = new SqlCommand(Sql, connection); if (commandParameters != null) { foreach (SqlParameter parm in commandParameters) command.Parameters.Add(parm); } connection.Open(); sdr = command.ExecuteReader(); // 关闭连接但保持读取器打开,因为后续代码可能需要继续读取数据 connection.Close(); } return sdr; } ``` 在这个方法中,创建了一个新的`SqlCommand`并打开数据库连接,然后执行SQL查询,并返回一个`SqlDataReader`。`using`语句确保`SqlConnection`被正确关闭,但`SqlDataReader`并未在`using`块内关闭,因为它可能在其他地方继续被使用。 然后是`setValue`方法: ```csharp public void setValue(string id) { try { SqlParameter[] paralist = { new SqlParameter("@id", SqlDbType.Int) }; paralist[0].Value = Convert.ToInt32(id); string setSql = "select Air, class, discountRate, discountName, ei, bznotes from ClassInfo where id=@id"; sqlHelper = new sqlHelper(); // 假设sqlHelper是一个辅助类,用于执行SQL操作 SqlDataReader sdr = null; sdr = sqlHelper.GetSqlDataReader(setSql, paralist); if (sdr != null) { if (sdr.Read()) { this.txtAir.Text = sdr["Air"].ToString(); this.txtCabin.SelectedText = sdr["class"].ToString(); } } } catch {} } ``` 在`setValue`方法中,同样使用了`GetSqlDataReader`获取数据。当调用`Read()`时,如果在此之前没有正确关闭上一次的`SqlDataReader`(如在`GetSqlConnection`方法中),则会抛出异常。此外,`catch`语句表明这里没有处理可能出现的异常,可能导致程序异常终止。 问题的关键在于,每次执行数据库查询后,应确保相应的`SqlDataReader`对象被关闭,以释放系统资源并避免潜在的数据不一致。在C#中,通常的做法是在不再需要数据时手动调用`SqlDataReader.Close()`,或者在`using`语句中自动关闭它,这样可以确保在读取完毕后自动关闭。 为了修复这个问题,可以在`GetSqlDataReader`方法中修改`connection.Close()`语句的位置,使其紧跟在`sdr = command.ExecuteReader();`之后,或者在`setValue`方法的`if (sdr != null)`条件结束后添加`sdr.Close()`。同时,建议在`catch`块中添加适当的异常处理,以便在遇到错误时能够得到明确的错误信息和适当的程序行为。 总结来说,当在C#中处理数据库读取器时,务必注意在适当的时候关闭`SqlDataReader`以避免资源泄露和错误提示。通过调整代码结构,确保在不再需要数据时及时关闭,可以有效解决“Reader is closed”这类问题。