以前做开发时,在最后阶段会发生数据库字段部分的变化,如果在某表中增加了一些字段,那可真是一场恶梦,前几天在微软的MSDN上看到一篇关于前台窗口控件与事务逻辑动态绑定的例子(http://www.microsoft.com/china/msdn/library/webservices/asp.net/aspformbinding.mspx),使用了反射,我在使用时做了一下测试,发现效率还可以接受,但由于代码中未提供事务逻辑与数据库类字段的接口,多少有点遗憾,所以我把我加的这部分代码在这里解释一下,请各位大侠多多指教。(代码发布在http://mxjlb.ccwb.net/dbservice.rar) using System; using System.Data; using System.Reflection; using System.Configuration; namespace DbService { /// <summary> /// DataObjBinding 的摘要说明。 /// </summary> public class DataObjBinding { public DataObjBinding() { // // TODO: 在此处添加构造函数逻辑 // }
public static string [] GetTableColum(string tablename) //在WEB.config中写入表的字段信息。 {
string [] strColumn=ConfigurationSettings.AppSettings[tablename].ToLower().Split(','); return strColumn; }
/// <summary> /// BindDataToClassProperty 的摘要说明。 /// 数据库表对象到相应的类对象的属性捆定,并将数据记录赋值于相应对象 /// obj 是前台类对象 /// TableName 要查询的表名 /// Condition 要查询的条件 /// </summary> public static void BindDataToClassProperty(object obj,string TableName, string Condition) { Type objType =obj.GetType(); //反射当前类的所有属性 PropertyInfo[] objPropertiesArray = objType.GetProperties(); string RowData="";//用于获得数据库的常量
DataRow daiRow=DbAccess.Select(TableName,GetTableColum(TableName),Condition).Tables[0].Rows[0]; foreach(DataColumn c in DbAccess.Select(TableName,GetTableColum(TableName),Condition).Tables[0].Columns) { RowData=daiRow[c.ToString()].ToString(); foreach (PropertyInfo objProperty in objPropertiesArray) { // 检查匹配的名称和类型 if (objProperty.Name.ToUpper() == c.ToString().ToUpper()) { // 将控件的属性设置为业务对象属性值 try { if (RowData=="True") RowData="1"; //如果是真假类型 if (RowData=="False") RowData="0"; objProperty.SetValue(obj, RowData , null); //return true; } catch { //return false; } } } //return false; } // return false; }
/// <summary> /// BindClassPropertyToData 的摘要说明。 /// 相应的类对象的属性捆定到数据库表对象,并将数据记录赋值于相应对象 /// obj 是前台类对象 /// TableName 要查询的表名 /// Condition 要查询的条件 /// </summary> public static void BindClassPropertyToData(object obj,string TableName, string Condition) { Type objType =obj.GetType(); //反射当前类的所有属性 PropertyInfo[] objPropertiesArray = objType.GetProperties(); int ColumnNum=0; //当前列的序列号 object[] strValue=new object[GetTableColum(TableName).Length] ; // 初始化要返回的对象 字符串在webconfig中 foreach(string c in GetTableColum(TableName)) { foreach (PropertyInfo objProperty in objPropertiesArray) { // 检查匹配的名称和类型 if (objProperty.Name.ToUpper() == c.ToString().ToUpper()) { // 将控件的属性设置为业务对象属性值 try { strValue[ColumnNum]= objProperty.GetValue(obj, null).ToString(); //return true; } catch { //return false; } } } ColumnNum++; //return false; } DbAccess.Update(TableName,GetTableColum(TableName),strValue,Condition); }
/// <summary> /// BindClassPropertyToData 的摘要说明。 /// 相应的类对象的属性捆定到数据库表对象,并将数据记录赋值于相应对象 /// obj 是前台类对象 /// TableName 要查询的表名 /// Opera 操作的类型 0:为插入 /// </summary> /// public static void BindClassPropertyToData(object obj,string TableName, int Opera) { Type objType =obj.GetType(); //反射当前类的所有属性 PropertyInfo[] objPropertiesArray = objType.GetProperties(); int ColumnNum=0; //当前列的序列号 object[] strValue=new object[GetTableColum(TableName).Length] ; // 初始化要返回的对象 字符串在webconfig中 foreach(string c in GetTableColum(TableName)) { foreach (PropertyInfo objProperty in objPropertiesArray) { // 检查匹配的名称和类型 if (objProperty.Name.ToUpper() == c.ToString().ToUpper()) { // 将控件的属性设置为业务对象属性值 try { strValue[ColumnNum]= objProperty.GetValue(obj, null).ToString(); //return true; } catch { //return false; } } } ColumnNum++; //return false; } if (Opera==0) { strValue[0]=DbAccess.SelectMaxID(TableName,TableName+"ID"); DbAccess.Insert(TableName,GetTableColum(TableName),strValue); } } } }
这样将来如果改了数据库,只要使用webconfig中的指定关键字的值,并修改相应的数据库类代码就OK了,不再需要去做别的修改了 。我的例子的数据库连接类采用了抽象类工厂的设计模式,它的好处相信各位早就知道了。 
|