已有打开的与此命令相关联的DataReader,必须首先将它关闭。对于此异常的理解
程序员文章站
2024-03-06 11:28:07
首先声明以下几点: 1、也许讲解有点初级,希望高手不要“喷”我,因为我知道并不是每一个人都是高手,我也怕高手们说我装13; 2、如有什么不对的地方,还希望大家指出,一定虚心...
首先声明以下几点:
1、也许讲解有点初级,希望高手不要“喷”我,因为我知道并不是每一个人都是高手,我也怕高手们说我装13;
2、如有什么不对的地方,还希望大家指出,一定虚心学习;
3、本文属于作者原创,尊重他人劳动成果,转载请注明作者,谢谢。
下面开讲:
开始在遇到此问题的时候我也在网上查了很多资料,貌似没找到什么好的解决方法,然后我就开始调试程序,我发现有的时候运行不报错,有的时候运行报错,这就很纠结了,但是后来我发现我把asp.net development server - 端口 xxx退出,然后再运行程序就不报错了...我以为是好了,可以后来我有发现一个问题,只要端口没关或者程序运行时候把页面不停的刷新,就会报错“已有打开的与此命令相关联的datareader,必须首先将它关闭。”
我火了,我开始把程序下n个断点,一步调试,我也没发现我是用了datareader对象啊,这就奇怪了,为什么我没用datareader对象,它却包这样的错误?我很是无语也。经过我反复的推敲,终于找到了解决的办法,原来这个异常不一定跟datareader有关哦,也有可能跟connection对象有关哦!
看下面代码:
private static sqlconnection sqlconnection;
public static sqlconnection sqlconnection
{
get
{
string sqlconnectionstring = system.configuration.configurationmanager.connectionstrings["tandytang"].tostring();
if (sqlconnection == null)
{
sqlconnection = new sqlconnection(sqlconnectionstring);
sqlconnection.open();
}
else if (sqlconnection.state == system.data.connectionstate.closed)
{
sqlconnection.open();
}
else if (sqlconnection.state == system.data.connectionstate.broken)
{
sqlconnection.close();
sqlconnection.open();
}
return sqlconnection;
}
}
///<summary>
/// sqlgetdatatable
///<param name="proc"></param>
///<param name="type"></param>
///<param name="param"></param>
///<param name="count"></param>
///<returns>datatable</returns>
public static datatable sqlgetdatatable(string proc, commandtype type, string[] param, out int count)
{
dataset ds = new dataset();
using (sqlcommand cmd = new sqlcommand(proc, sqlconnection))
{
sqlparameter[] myparms = new sqlparameter[2];
myparms[0] = new sqlparameter("@id", sqldbtype.int, 4);
myparms[0].value = paramvalue[0];
myparms[1] = new sqlparameter("@name", sqldbtype.varchar, 50);
myparms[1].value = paramvalue[1];
foreach (sqlparameter parameter in myparms)
{
cmd.parameters.add(parameter);
}
cmd.commandtype = type;
sqldataadapter da = new sqldataadapter(cmd);
da.fill(ds);
}
return ds.tables[0];
}
以上代码,我相信在一般人看来,应该都没问题,我也认为没什么问题。第一段代码是创建数据连接,并打开数据库连接,第二段代码是创建一个sqlcommand,其中要用到sqlconnection作为第一个参数,这就是问题的关键。
如果在页面上值运行一遍sqlgetdatatable()方法就不会出任何问题,如果不停的页面的刷新页面就“已有打开的与此命令相关联的datareader,必须首先将它关闭。”这样的异常(也许不会出现哦,你试试就知道了。代码红色字体部分就是出现错误提示的地方)
经过我的思考,终于找到了解决的办法,解决办法如下,看下面代码:
private static string connectionstring = system.configuration.configurationmanager.connectionstrings["tandytang"].connectionstring;
///<summary>
/// sqlgetdatatable
///<param name="proc"></param>
///<param name="type"></param>
///<param name="param"></param>
///<param name="count"></param>
///<returns>datatable</returns>
public static datatable sqlgetdatatable(string proc, commandtype type, string[] param, out int count)
{
dataset ds = new dataset();
using (sqlconnection con = new sqlconnection(connectionstring))
{
using (sqlcommand cmd = new sqlcommand(proc, con))
{
sqlparameter[] myparms = new sqlparameter[11];
myparms[0] = new sqlparameter("@id", sqldbtype.int, 4);
myparms[0].value = paramvalue[0];
myparms[1] = new sqlparameter("@name", sqldbtype.varchar, 50);
myparms[1].value = paramvalue[1];
foreach (sqlparameter parameter in myparms)
{
cmd.parameters.add(parameter);
}
cmd.commandtype = type;
using (sqldataadapter da = new sqldataadapter(cmd))
{
da.fill(ds);
}
}
return ds.tables[0];
}
}
应该发现有什么不同的地方了吧,上面的方法,没用用到sqlconnection方法,而是把sqlconnection对象写到using(){}里面的。
ps:个人建议大家不要用第一种方法,也许会遇到很的麻烦的哦,个人建议多用using(){}语句把ado.net的没对象都放到using(){}里面最好了,using(){}的好处我想大家也都知道,所以我也不做过多的解释了。
1、也许讲解有点初级,希望高手不要“喷”我,因为我知道并不是每一个人都是高手,我也怕高手们说我装13;
2、如有什么不对的地方,还希望大家指出,一定虚心学习;
3、本文属于作者原创,尊重他人劳动成果,转载请注明作者,谢谢。
下面开讲:
开始在遇到此问题的时候我也在网上查了很多资料,貌似没找到什么好的解决方法,然后我就开始调试程序,我发现有的时候运行不报错,有的时候运行报错,这就很纠结了,但是后来我发现我把asp.net development server - 端口 xxx退出,然后再运行程序就不报错了...我以为是好了,可以后来我有发现一个问题,只要端口没关或者程序运行时候把页面不停的刷新,就会报错“已有打开的与此命令相关联的datareader,必须首先将它关闭。”
我火了,我开始把程序下n个断点,一步调试,我也没发现我是用了datareader对象啊,这就奇怪了,为什么我没用datareader对象,它却包这样的错误?我很是无语也。经过我反复的推敲,终于找到了解决的办法,原来这个异常不一定跟datareader有关哦,也有可能跟connection对象有关哦!
看下面代码:
复制代码 代码如下:
private static sqlconnection sqlconnection;
public static sqlconnection sqlconnection
{
get
{
string sqlconnectionstring = system.configuration.configurationmanager.connectionstrings["tandytang"].tostring();
if (sqlconnection == null)
{
sqlconnection = new sqlconnection(sqlconnectionstring);
sqlconnection.open();
}
else if (sqlconnection.state == system.data.connectionstate.closed)
{
sqlconnection.open();
}
else if (sqlconnection.state == system.data.connectionstate.broken)
{
sqlconnection.close();
sqlconnection.open();
}
return sqlconnection;
}
}
///<summary>
/// sqlgetdatatable
///<param name="proc"></param>
///<param name="type"></param>
///<param name="param"></param>
///<param name="count"></param>
///<returns>datatable</returns>
public static datatable sqlgetdatatable(string proc, commandtype type, string[] param, out int count)
{
dataset ds = new dataset();
using (sqlcommand cmd = new sqlcommand(proc, sqlconnection))
{
sqlparameter[] myparms = new sqlparameter[2];
myparms[0] = new sqlparameter("@id", sqldbtype.int, 4);
myparms[0].value = paramvalue[0];
myparms[1] = new sqlparameter("@name", sqldbtype.varchar, 50);
myparms[1].value = paramvalue[1];
foreach (sqlparameter parameter in myparms)
{
cmd.parameters.add(parameter);
}
cmd.commandtype = type;
sqldataadapter da = new sqldataadapter(cmd);
da.fill(ds);
}
return ds.tables[0];
}
以上代码,我相信在一般人看来,应该都没问题,我也认为没什么问题。第一段代码是创建数据连接,并打开数据库连接,第二段代码是创建一个sqlcommand,其中要用到sqlconnection作为第一个参数,这就是问题的关键。
如果在页面上值运行一遍sqlgetdatatable()方法就不会出任何问题,如果不停的页面的刷新页面就“已有打开的与此命令相关联的datareader,必须首先将它关闭。”这样的异常(也许不会出现哦,你试试就知道了。代码红色字体部分就是出现错误提示的地方)
经过我的思考,终于找到了解决的办法,解决办法如下,看下面代码:
复制代码 代码如下:
private static string connectionstring = system.configuration.configurationmanager.connectionstrings["tandytang"].connectionstring;
///<summary>
/// sqlgetdatatable
///<param name="proc"></param>
///<param name="type"></param>
///<param name="param"></param>
///<param name="count"></param>
///<returns>datatable</returns>
public static datatable sqlgetdatatable(string proc, commandtype type, string[] param, out int count)
{
dataset ds = new dataset();
using (sqlconnection con = new sqlconnection(connectionstring))
{
using (sqlcommand cmd = new sqlcommand(proc, con))
{
sqlparameter[] myparms = new sqlparameter[11];
myparms[0] = new sqlparameter("@id", sqldbtype.int, 4);
myparms[0].value = paramvalue[0];
myparms[1] = new sqlparameter("@name", sqldbtype.varchar, 50);
myparms[1].value = paramvalue[1];
foreach (sqlparameter parameter in myparms)
{
cmd.parameters.add(parameter);
}
cmd.commandtype = type;
using (sqldataadapter da = new sqldataadapter(cmd))
{
da.fill(ds);
}
}
return ds.tables[0];
}
}
应该发现有什么不同的地方了吧,上面的方法,没用用到sqlconnection方法,而是把sqlconnection对象写到using(){}里面的。
ps:个人建议大家不要用第一种方法,也许会遇到很的麻烦的哦,个人建议多用using(){}语句把ado.net的没对象都放到using(){}里面最好了,using(){}的好处我想大家也都知道,所以我也不做过多的解释了。