编写SqlHelper使用,在将ExecuteReader方法封装进而读取数据库中的数据时会产生Additional information: 阅读器关闭时尝试调用 Read 无效问题,解决方法与解释

时间:2023-12-10 11:50:26

在自学杨中科老师的视频教学时,拓展编写SqlHelper使用,在将ExecuteReader方法封装进而读取数据库中的数据时

会产生Additional information: 阅读器关闭时尝试调用 Read 无效问题,错误产生时,我的代码如下:

SqlHelper.cs代码如下:

public static SqlDataReader ExecuteReader(string sql)

        {

            using (SqlConnection conn = new SqlConnection(ConnString))

            {

                conn.Open();

                using (SqlCommand cmd = conn.CreateCommand())

                {

                    cmd.CommandText = sql;

                    return  cmd.ExecuteReader();

                }

            }

        }

运行主程序代码如下:

private void btn2_Click(object sender, RoutedEventArgs e)

        {

            using (SqlDataReader reader = SqlHelper.ExecuteReader("select * from T_Student"))

            {

                while (reader.Read())

                {

                    string H = reader["Hobbit"].ToString();

                    MessageBox.Show("爱好分别为:" + H);



                }

            }

       }

运行出错抛异常如下图:

编写SqlHelper使用,在将ExecuteReader方法封装进而读取数据库中的数据时会产生Additional information: 阅读器关闭时尝试调用 Read 无效问题,解决方法与解释

也就是:      Additional information: 阅读器关闭时尝试调用 Read 无效

解决方法:

将SqlHelper.cs代码改为:

public static SqlDataReader ExecuteReader(string sql)

        {

            SqlConnection conn = new SqlConnection(ConnString);

            

                conn.Open();

                using (SqlCommand cmd = conn.CreateCommand())

                {

                    cmd.CommandText = sql;

                    return  cmd.ExecuteReader();

                }

            

        }

与原SqlHelper.cs的区别在于将创建数据库连接对象的using(){     }方法去掉!其他运行程序代码不变!

这样运行后将不会再出现异常,能正常从数据库中读取数据了!!!

解决方法解释:

看到这篇文章大家对using(){  }方法有一定的了解,它的作用就是在其“()”中声明创建对象并在“{  }”中使用后,自动将其占用的系统资源释放!相当于try-finally的作用,创建数据库连接,使用后,将数据库再关闭一样。

因此就有了,在SqlHelper.cs中,如果在数据库声明创建时使用using(){  },那么在主程序运行到“SqlDataReader reader = SqlHelper.ExecuteReader("select * from T_Student")”时,调用SqlHelper.cs中的ExecuteReader()已经结束,系统已经将数据库所占用的资源已经释放,由于要使用返回的SqlDataHelper所以不能关闭连接,那样阅读器SqlDataHelper已经被释放,那它相应的Read()方法还能被调用吗,这肯定不行,所以要将数据库声明连接时的sing(){
 }去掉!

同时应注意正常从数据库读取数据时,ExecuteReader读出的数据是在服务器端,要想读取显示就必须使数据库是连接着的;而DataSet则是用于小量的数据的存储,它是将数据从服务器都出来后,直接放到客户端,服务器连接断开后,它的数据还是存储在客户端的,因而还能被显示出来!!!

注意:在改正运行后,要将数据库关闭,因为没用using(){  }去释放数据库连接,这时手动关闭数据库在上述主程序结尾加上reader.Close();

忙了一下午解决这个问题,正准备写一篇,结果上网看到了相似的问题及解决方法,写的比我还好的多得多!!!!有点心痛哎,原来早有前辈写好了,没办法只有将原创改为转载了!!!呵呵呵...

不过没事,多写一遍就多想一遍记忆就更深一些了,别人也就更快一些的找到此问题的解决方法并掌握它,毕竟多了我这一篇!!那位前辈的相似问题解决方法地址:点击打开链接 如果看我的还理解不了的可以看看这位前辈写的,比我好得多了,哈哈哈...

)的相关问题地址  写的比我好的多了,大家看我这篇写理解的还不够透彻的话,建议看这位前辈的!!!!!!!!!!!!!!