从牛人那儿学习了关于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:
Post a Comment