封装一个获取SqlDataReader的方法,在调用时报错:“阅读器关闭时尝试调用 Read 无效”

本文介绍了一种在使用SQLDataReader时遇到的“阅读器关闭时尝试调用Read无效”异常的解决方案。通过调整代码逻辑并利用CommandBehavior.CloseConnection特性,确保在SqlDataReader对象关闭时其依赖的连接也会被自动关闭。
摘要由CSDN通过智能技术生成

哇,这个问题真的好烦啊,在出现这个问题后查了好久的资料,最终在ID为“zhang_wj123”的大佬博客中发现了思路,在此感谢大佬

首先贴代码

{
        SqlConnection conn = new SqlConnection();
        string connStr = @"Data Source = TAOR\TAOR;Initial Catalog = 02.车辆; Integrated Security = True";
        //string connStr = "Data Source=.;Initial Catalog=02.车辆;Integrated Security=True";

        //方法一:只读查询所需数据
        public SqlDataReader GetReader(string sql_a, SqlParameter[] para)
        {
            conn = new SqlConnection(connStr);
            conn.Open();
            SqlCommand com_a = new SqlCommand(sql_a, conn);

            foreach (SqlParameter parameter in para)
            {
                com_a.Parameters.Add(parameter);
            }

            /*另一种思路
            for(int i=1;i<=para.Length;i++)
            {com_a.Parameters.AddRange(para);}
            */

            /*第三种思路
            com_a.Parameters.AddRange(para);//添加参数组
            */

            SqlDataReader RD_a = com_a.ExecuteReader();
            RD_a.Close();
            conn.Close();
            return RD_a;//此处出现问题
        }
}

RT,觉得上面啰嗦的话,核心代码即

conn = new SqlConnection(connStr);
            conn.Open();
            SqlCommand com_a = new SqlCommand(sql_a, conn);

            foreach (SqlParameter parameter in para)
            {
                com_a.Parameters.Add(parameter);
            }

            SqlDataReader RD_a = com_a.ExecuteReader();
            RD_a.Close();
            conn.Close();
            return RD_a;//此处出现问题

这是用GetReader 来获取一个SqlDataReader。但是在调用运行后会显示“阅读器关闭时尝试调用 Read 无效”

这是因为Reader与DataSet不同,DataSet已经将数据保存在本地内存中,而Reader并没有将数据保存在本地内存中。

出了封装的范围后,con.close()生效后,返回的sqldataReader毫无用处,其只能在连接范围内使用

此时不能关闭连接,也不能保持连接打开状态。很多系统为了解决这样两难的境地,只能放弃使用Reader模式的数据源,或者把连接对象交给方法调用者,以便进行关闭。


解决这个问题的方法很简单

CommandBehavior.CloseConnection

通过这句代码,即可以完成我们想要的功能。

这句代码的作用是能够保证当SqlDataReader对象被关闭时,其依赖的连接也会被自动关闭。

即只有在调用的sqldataReader关闭后,连接才会关闭

因此代码修改如下,即可以解决问题

SqlDataReader RD_a = com_a.ExecuteReader(CommandBehavior.CloseConnection);
            return RD_a;
            
            /*修改为上述代码
            RD_a.Close();
            conn.Close();
            return RD_a;//此处出现问题
            */
RT。


附:附带主函数部分代码如下:

private void button1_Click(object sender, EventArgs e)
        {
            double miles;
            string ChePai;
            string result=null;
            
            miles = Convert.ToDouble(textBox2.Text);
            ChePai = textBox1.Text;

            string str1 = null;
            str1 = "select LeiXing from Vehicle where ChePai=@chepai";

            //这里的地方用于循环添加新的sqlparameter的值
            SqlParameter[] str_sqlPara =
            {
                new SqlParameter("@chepai",SqlDbType.NChar,10),
            };
            str_sqlPara[0].Value = ChePai;
            
            SQLDataHelper reResult = new SQLDataHelper();//实例化一个对象为自建的sqldatahelper类
            SqlDataReader dr = reResult.GetReader(str1, str_sqlPara);
            
            while (dr.Read())
            {
                result = dr[0].ToString();
            }
            
            Vehicle v = null;
            //设定汽车 公交 卡车 依次为1 2 3 
            if (result == "1") v = new Car();
            if (result == "2") v = new Bus();
            if (result == "3") v = new Truck();
            label4.Text = ChePai + "号 收费" + v.JinE(miles) + "元";

            dr.Close();
        }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值