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

  • 相关阅读:
    jQuery 语法
    jQuery 简介
    把数据存储到 XML 文件
    XML 注意事项
    XML DOM (Document Object Model) 定义了访问和操作 XML 文档的标准方法。
    通过 PHP 生成 XML
    XML 命名空间(XML Namespaces)
    XML to HTML
    XMLHttpRequest 对象
    使用 XSLT 显示 XML
  • 原文地址:https://www.cnblogs.com/studingASPNet/p/2226371.html
Copyright © 2011-2022 走看看