SqlDataReader的关闭问题,报错:“阅读器关闭时尝试调用 Read 无效”

来源:互联网 发布:卢松松博客php版 编辑:程序博客网 时间:2024/05/20 22:04

最近学习了一下ADO.NET,我想封装一个获取SqlDataReader的方法供别处调用,

但是遇到了一些问题,最后找到了解决方法。
封装的时候如果用using{}将连接及执行等过程括起来,这样可以保证最后关闭连

接,但是调用时却会出错。

最初我封装的代码是这样的:

public static SqlDataReader GetDataReader(string sql, params SqlParameter[] parameters)    {        using (SqlConnection conn = new SqlConnection(connstr))        {            SqlCommand cmd = new SqlCommand(sql, conn);            foreach (SqlParameter parameter in parameters)            {                cmd.Parameters.Add(parameter);            }            try            {                conn.Open();                SqlDataReader dr = cmd.ExecuteReader();                return dr;            }            catch (Exception e)            {                throw new Exception("执行任务失败:" + e.Message + "   "+ sql);            }        }    }

用这样的方法进行封装时,调用GetDataReader方法报错:“阅读器关闭时尝试调用 Read 无效”。这是因为出了using{}的作用域之后,连接自动关闭,而Reader与DataSet不同,DataSet已经将数据保存在本地内存中,而Reader并没有将数据保存在本地内存中,可以理解成只是指向了数据,连接关闭后用reader读取数据当然无法实现。
于是我参考许多资料后,对我的代码进行了修改,并且验证了网上几个说法不一
的问题。

修改后的代码如下:

public static SqlDataReader GetDataReader(string sql, params SqlParameter[] parameters)    {        SqlConnection conn = new SqlConnection(connstr);        SqlCommand cmd = new SqlCommand(sql, conn);        foreach (SqlParameter parameter in parameters)        {            cmd.Parameters.Add(parameter);        }        try        {            conn.Open();            SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);//关闭SqlDataReader 会自动关闭Sqlconnection            return dr;        }        catch (Exception e)        {            throw new Exception("执行任务失败:" + e.Message + "   " + sql);        }                }


这样封装好之后,我在一个网页的后台代码中进行了调用:

protected void TextBoxName_TextChanged(object sender, EventArgs e)    {        string UserN = TextBoxName.Text;        string strsql = "select * from UserInfo where UI01=@UserName";        SqlDataReader dr = DBN.GetDataReader(strsql, new SqlParameter("UserName", UserN));        if (dr.Read())        {            Response.Write("<script language='javascript'>alert('该用户名已存在');</script>");            TextBoxName.Text = null;        }        dr.Close();//采用了close进行手动关闭。         Response.Write(dr.IsClosed.ToString() + "<br/>");//查看SqlDataReader的状态    }

这样就没有在报错:“阅读器关闭时尝试调用 Read 无效”了。这里需要说明的是,在数据读取完毕之后,不再需要SqlDataReader时,必须将其进行手动关闭。因为cmd.ExecuteReader(CommandBehavior.CloseConnection)虽然可以实现关闭SqlDataReader后自动关闭连接,但是SqlDataReader必须手动关闭,上面的代码中如果去掉dr.Close(),则Response.Write(dr.IsClosed.ToString()+"<br/>")输出为False,也就是说指定的 SqlDataReader 实例没有关闭。
在MSDN中也有描述:在使用 SqlDataReader 时,关联的 SqlConnection 正忙于
为 SqlDataReader 服务,对 SqlConnection 无法执行任何其他操作,只能将其关闭。除非调用 SqlDataReader 的 Close 方法,否则会一直处于此状态。
由此看来,网上有人说不用手动关闭SqlDataReader的说法是不对的。


 

 


 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 微信q币冲错号码怎么办 支付宝转账到之前号码怎么办 qq红包收不了钱怎么办 qq抢红包要实名认证怎么办 支付宝被骗冲q币怎么办 qq发红包发错了怎么办 qq红包发不出来怎么办 qq红包发多了怎么办 qq发红包要短信验证怎么办 不是qq好友发了红包怎么办 苹果手机升级后支付宝打不开怎么办 qqq币充了没进帐怎么办 怎么办q币换成qq余额 支付宝qb冲多了怎么办 微信没钱怎么办怎么赚 忘记微信支付密码怎么办 手机设备注册达上限怎么办 在新手机上登微信需要验证怎么办 手机号被限制注册qq号怎么办 手机互换了微信怎么办 微信申诉只有一位好友怎么办 微信申诉没有好友怎么办 四川电信多余的话费怎么办 四川电信话费多了怎么办 固话冲q币要密码怎么办 手机卡怎么突然没了怎么办 联通话费冲错了怎么办 王卡高额半停机 怎么办 计算机报考在手机上网上支付怎么办 建行app充话费不到账怎么办 币乎账号被骗了怎么办? q币充了想返还怎么办 q币账号充值错了怎么办 淘宝乐充话费没到账怎么办 微信信用卡还款未到账怎么办 登不上qq怎么改qq密码怎么办 qq改不了以前的密码怎么办 qq微信密码都被改了怎么办 qq账号被盗一直改密码怎么办? 2018qq密码忘了怎么办 我qq密码忘记了怎么办