zoukankan      html  css  js  c++  java
  • cmd.Parameters.Clear() 语句的作用

    public static int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters)

    {

        SqlCommand cmd = new SqlCommand();

        using (SqlConnection conn = new SqlConnection(connectionString))

        {
            PrepareCommand(cmd, conn, null, cmdType, cmdText, commandParameters);
            int val = cmd.ExecuteNonQuery();
            cmd.Parameters.Clear();
            return val;
        }
    }

    private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms) {

        if (conn.State != ConnectionState.Open)
            conn.Open();

        cmd.Connection = conn;
        cmd.CommandText = cmdText;

        if (trans != null)
            cmd.Transaction = trans;

        cmd.CommandType = cmdType;

        if (cmdParms != null) {
            foreach (SqlParameter parm in cmdParms)
                cmd.Parameters.Add(parm);
        }
    }

      乍看之下cmd.Parameters.Clear() 语句似乎有此多于,因为执行完cmd.Parameters.Clear()语句后就是return语句了,这意味着cmd将成为垃圾回收器的回收对象,如果说是想及时释放资源的话那似乎不通,这个并不占用资源的对象都需要手动清理那要“托管”何用?于是到论坛上发贴请教。得到的答案很失望,有的说是编程习惯,有的解释Clear()是清零。于是Buidu一下,也有人问同样的问题,但结果一样令人失望。看来只能自己解决了,当我看到cmd.Parameters.Add(parm) 时发现cmd.Parameters是SqlParameterColeection类型的,而SqlParameterColeection在framework中有个怪脾气,“它不用别人用过的”,说得明白点就是:如果一个对象A被一个SqlParameterColeection引用后,此时有另一个SqlParameterColeection再引用A对象时就会发生异常(注意,SqlParameterColeection允许其它类型引用自己引用的对象,比如SqlParameter引用它所引用的对象也不会有问题,只要不是SqlParameterColeection就行)。这样就明天了。我们先删除cmd.Parameters.Clear()语句,然后下面的方面调用ExecuteNonQuery():

    string conn = "...";//连接字符串

    string sqlInsert = "INSERT INTO Cart ( Name,) VALUES ( @Name);";

    string sqlSelect = "SELECT * FROM Cart WHERE UniqueID=@UniqueID;";

    SqlParameter parms = new SqlParameter("@Name", "testUser");

    ExecuteNonQuery(conn, CommandType.Text, sqlInsert, parms);

    ExecuteNonQuery(conn, CommandType.Text, sqlSelect, parms);

    大家知道每次调用ExecuteNonQuery方法时它都会调用PrepareCommand方法,而PrepareCommand方法执行如下语句:

    cmd.Parameters.Add(parm);//添加parm的引用到类型为SqlParameterCollection的Parameters对象中


    当第一次调用ExecuteNonQuery时会有一个SqlParameterCollection引用parms,注意,这时第一次ExecuteNonQuery调用时产生的cmd还未被垃圾回收器回收,它依然引用着parms,直到真正被回收后,当第二次调用ExecuteNonQuery又会有另一个SqlParameterCollection(cmd.Parameters)将去引用parms,这样就会抛出异常了!!!

    当添加cmd.Parameters.Clear()后,再调用ExecuteNonQuery即将结果时引用parms的cmd.Parameters就解除了对parms的引用,引用?对!cmd.Parameters.Clear()语句确切的说是解除它对其它对象的引用,而不是清除它包含的对象,cmd.Parameters.Clear()解除对象引用后,它之前引用的对象还是存在的。所以无论ExecuteNonQuery被多次执行都不会有异常。当然,如果不加cmd.Parameters.Clear()语句也可以,那么上面的代码应该这样写:

    ExecuteNonQuery(conn, CommandType.Text, sqlInsert, new SqlParameter("@Name", "testUser"));

    ExecuteNonQuery(conn, CommandType.Text, sqlSelect, new SqlParameter("@Name", "testUser"));

     

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chenyiying37/archive/2010/08/08/5797090.aspx

  • 相关阅读:
    Feature分支
    Bug分支
    分支管理策略
    解决冲突
    创建与合并分支
    分支管理
    Java并发与多线程教程(1)
    Java Thread(线程)案例详解sleep和wait的区别
    Spring在Thread中注入Bean无效的解决方式
    浅谈Java中的hashcode方法
  • 原文地址:https://www.cnblogs.com/studingASPNet/p/2226371.html
Copyright © 2011-2022 走看看