一、
ado.net释放资源问题首先帖出代码 using (SqlConnection conn = new SqlConnection(SqlHelper.ConnectionStringLocalTransaction))
{
string sql="select * from tt.....";
conn.Open();
SqlCommand cmd=new SqlCommand(sql,conn);
//cmd添加参数
SqlDataReader dr=cmd.ExecuteReader();
if(dr.Read())//如果读到数据,我要更新数据库
{
string sql1="update tt set .....";
SqlCommand cmd1=new SqlCommand(sql1,conn);
//cmd1添加参数
cmd1.ExecuteNonQuery();
}
else//如果读不到数据,我要插入新的数据
{
string sql2="insert into tt(....)values(....)";
SqlCommand cmd2=new SqlCommand(sql2,conn);
//cmd2添加参数
cmd2.ExecuteNonQuery();
}
}
各位高人帮我看下,我这样写就出错了,报错为: 已有打开的与此命令相关联的 DataReader,必须首先将它关闭。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。异常详细信息: System.InvalidOperationException: 已有打开的与此命令相关联的 DataReader,必须首先将它关闭。主要想问的有2点:
1、我这样层层的嵌套数据库读写会有什么危害吗?到底这种写法正确不?
2、如果这样写行,如何修正这个错误?
3、如果这种写法不行,那按照我代码的意思,代码最好如何写?

解决方案 »

  1.   

    二、
    代码: string sql="update userInfo set uName='"+uname+"'";
    if(mynickname!="")
    sql+=",myNickName='"+mynickname+"'";
    if(myqq!="")
    sql+=",myQq='"+myqq+"'";
    sql+=" where uid='"+uid+"'";想用参数化查询达到上面拼接字符串的效果,但又不想拼接参数,要如何做呢?别不是存储过程吧
      

  2.   

    我在网上查了下,也说是打开了datareader,可是close写在哪呢?写在else里面吗?
      

  3.   

    SqlDataReader dr=cmd.ExecuteReader();
                        if(dr.Read())//如果读到数据,我要更新数据库
                        {
                            string sql1="update tt set .....";
                            SqlCommand cmd1=new SqlCommand(sql1,conn);
                            //cmd1添加参数
                            cmd1.ExecuteNonQuery();
                        }
    dr.Close();
      

  4.   

    不想拼接sql 用存储过程和sql参数话
    如 update userinfo set uName=@uName;
    SqlCommand cmd=new SqlCommand();
    cmd.Pat.....Add("@uName",sqldbtype.nvchar).value=uname;.....
      

  5.   

    还有一种可能,那就是你在调用数据库的方法中可能使用了static的方法,就可能造成这种问题,以前我在用ling的时候也是使用了static方法,Getlist这写方法,也是出这种问题。你也可以参考参考
      

  6.   

    我首先想要说的就是你的代码没有try catch finally 捕捉异常 ,如果你不想try catch finally ,你也应该使用using吧。用完了资源比如sqldatareader,这个必须立即的调用dispose()方法。
      

  7.   

    @4:我下面还有else,怎么能中间多一个close
    @5:你这个是参数化查询,可是我看不出来能达到根据条件进行参数化查询效果呢
    @6:我没有在此处使用static方法,都是直接操作数据库
    @7:我是用using呀,只不过想一次using做两次操作而已
      

  8.   

    SqlDataReader 要先关闭,再执行ExecuteNonQuery操作
    dr.Read();
    或using (SqlConnection cn = new SqlConnection(“”))
      {
      SqlCommand cmd1 = new SqlCommand("", cn);
      cn.Open();
      using (SqlDataReader dr1 = cmd1.ExecuteReader())
      {
      while (dr1.Read())
      {
      string sql= "";
      SqlConnection conn2 = new SqlConnection("");
      SqlCommand cmd2 = new SqlCommand(sql, conn2 );
      cmd2.ExecuteNonQuery();
      }
      }  }
      

  9.   

           using (SqlConnection conn = new SqlConnection(SqlHelper.ConnectionStringLocalTransaction))
                    {
                        string sql="select * from tt.....";
                        conn.Open();
                        SqlCommand cmd=new SqlCommand(sql,conn);
                        //cmd添加参数
                        SqlDataReader dr=cmd.ExecuteReader();                    bool aa = dr.Read();
                        dr.close();
                        if(aa)//如果读到数据,我要更新数据库
                        {
                            string sql1="update tt set .....";
                            SqlCommand cmd1=new SqlCommand(sql1,conn);
                            //cmd1添加参数
                            cmd1.ExecuteNonQuery();
                        }
                        else//如果读不到数据,我要插入新的数据
                        {
                            string sql2="insert into tt(....)values(....)";
                            SqlCommand cmd2=new SqlCommand(sql2,conn);
                            //cmd2添加参数
                            cmd2.ExecuteNonQuery();
                        }
                    }
    这应该能解决你第一个问题了..第二个就不知道了..我也经常拼字符串