Tuesday, April 21, 2009

从牛人那儿学习了关于using及数据库操作时注意释放资源的问题

从牛人那儿学习了关于using及数据库操作时注意释放资源的问题
这些平时都是直接用,没有去想为什么这样作,有更好的实现吗?


以下是部分代码,我们将由这些代码来说开去(当然是关于上述主题的,当作是我的复习吧,在此深深地感受到有人指点和讨论是比一个人从网上找资料,一个人学习要有效率得多。在此感谢这两位牛人的指教)



protected void Page_Load(object sender, EventArgs e)
        {
            string ccon = new SqlDataProvider().ConnectionString;
            SqlConnection con = new SqlConnection(ccon);
              SqlDataAdapter da=null;
            try
            {
                if (!IsPostBack)
                {
                   


                    con.Open();
                    string oSql = "select BookID,  TelNumber,BWK_120BookIn.CreatedDate,  'CreatedByUserName' = Users.FirstName  + Users.LastName ,  BWK_120CallType.CallTypeName,  BWK_120Symptom.SymptomName,      SickingPlace,CarPlace from BWK_120BookIn inner join Users on BWK_120BookIn.CreatedByUser = Users.UserId  inner join BWK_120CallType on BWK_120BookIn.CallTypeID = BWK_120CallType.CallTypeID   inner join BWK_120Symptom on BWK_120BookIn.SymptomID =  BWK_120Symptom.SymptomID";
                    //从数据库中提取数据 
                  da = new SqlDataAdapter(oSql, con);
                    //创建和声明记录集对象 
                    DataSet ds = new DataSet();
                    //将数据库中提取出的数据加载到记录集 
                    da.Fill(ds, "BookIn");
                     
                    
                    
                    //从记录集中获取表对象 
                    DataTable dt = ds.Tables["BookIn"];
                    //设定要过滤的的条件字符串 
                    string filterExpression = "CreatedByUserName='SuperUserAccount'";
                    //设置要排序的字段和排序方式字符串 
                    string sortExpression = "BookID aSC";
                    //行状态过滤设置为原先的行 
                    DataViewRowState
                    rowStateFilter = DataViewRowState.OriginalRows;

                    //DataView dv=new DataView(dt,filterExpression,sortExpression,rowStateFilter); 
                    //创建DataView对象并向其构造函数传递参数 
                    //在生成DataView后分别设置Table、RowFilter、Sort、RowStateFilter属性 
                    //下面是分步设置 
                    //创建DataView对象 
                    dv = new DataView();
                    //获取数据 
                    dv.Table = dt;
                    //设置过滤属性 
                    dv.RowFilter = filterExpression;
                    //设置排序属性 
                    dv.Sort = sortExpression;
                    //执行过滤 
                    dv.RowStateFilter = rowStateFilter;



                    GridView1.DataSource = dv;
                    GridView1.DataBind();
                    //ReportViewer1.LocalReport.ReportPath =strPart
                }
            }
            catch (Exception ex)
            {
                Exceptions.ProcessModuleLoadException(this, ex);
            }
            finally
            {
                con.Close();
                da.Dispose();

            }
        }

上面的代码,是使用finally来关闭数据库连接和SqlDataAdapter的。无论代码是否执行出错,finally都会被执行,这样保证了数据库资源的释放,不会因此造成数据库的问题。
我原来以为,所有的东西,都有.net framework来收拾残局,随便写,今天才知道,关于数据库的一些东西,.net Framework是管不了的。还得自己写代码时,考虑到。

这位牛人还在考虑其他解决方式,有很多,我印象很深的是使用using。以前我是看过代码中使用using的,不过,我没有真正理解using出现在实现代码中的作用。

好,还是来看上述代码的using实现版:


 protected void Page_Load(object sender, EventArgs e)
        {



            try
            {
                if (!IsPostBack)
                {
                    string ccon = new SqlDataProvider().ConnectionString;


                    using (SqlConnection con = new SqlConnection(ccon))
                    {
                        con.Open();
                        string oSql = "select BookID,  TelNumber,BWK_120BookIn.CreatedDate,  'CreatedByUserName' = Users.FirstName  + Users.LastName ,  BWK_120CallType.CallTypeName,  BWK_120Symptom.SymptomName,      SickingPlace,CarPlace from BWK_120BookIn inner join Users on BWK_120BookIn.CreatedByUser = Users.UserId  inner join BWK_120CallType on BWK_120BookIn.CallTypeID = BWK_120CallType.CallTypeID   inner join BWK_120Symptom on BWK_120BookIn.SymptomID =  BWK_120Symptom.SymptomID";
                        //从数据库中提取数据 
                        using (SqlDataAdapter da = new SqlDataAdapter(oSql, con))
                        {
                            //创建和声明记录集对象 
                            DataSet ds = new DataSet();
                            //将数据库中提取出的数据加载到记录集 
                            da.Fill(ds, "BookIn");
                            //关闭数据库 


                            //从记录集中获取表对象 
                            DataTable dt = ds.Tables["BookIn"];
                            //设定要过滤的的条件字符串 
                            string filterExpression = "CreatedByUserName='SuperUserAccount'";
                            //设置要排序的字段和排序方式字符串 
                            string sortExpression = "BookID aSC";
                            //行状态过滤设置为原先的行 
                            DataViewRowState
                            rowStateFilter = DataViewRowState.OriginalRows;

                            //DataView dv=new DataView(dt,filterExpression,sortExpression,rowStateFilter); 
                            //创建DataView对象并向其构造函数传递参数 
                            //在生成DataView后分别设置Table、RowFilter、Sort、RowStateFilter属性 
                            //下面是分步设置 
                            //创建DataView对象 
                            dv = new DataView();
                            //获取数据 
                            dv.Table = dt;
                            //设置过滤属性 
                            dv.RowFilter = filterExpression;
                            //设置排序属性 
                            dv.Sort = sortExpression;
                            //执行过滤 
                            dv.RowStateFilter = rowStateFilter;



                            GridView1.DataSource = dv;
                        } GridView1.DataBind();
                    }
                }    //ReportViewer1.LocalReport.ReportPath =strPart
            }

            catch (Exception ex)
            {
                Exceptions.ProcessModuleLoadException(this, ex);
            }

        }



这样实现了只要离开了这个代码段就自动调用这个对象的Dispose。



当ccon对象出错时,直接就跳出这个using的{}范围,并且Dispose,同样,当da出错也是。
即使正常执行下去,也是当执行到using的{}范围外时,会Dispose相应的对象。

No comments:

Search This Blog

Followers