三层架构下的增删改查
三层架构下的增删改查
文档编号:
文档名称:三层架构下的增删改查
文档类别:技术文档
版本信息:V0.5
建立日期:
编辑软件:Microsoft Office 2003 中文版
文档修订记录
版本编号 |
*变化 状态 |
简要说明(变更内容和变更范围) |
日期 |
变更人 |
批准日期 |
批准人 |
更改请求号 |
V0.5 |
C |
创建 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*变化状态:C——创建,A——添加,M——修改,D——删除
文档审批信息
序号 |
审批人 |
角色 |
审批日期 |
签字 |
备注 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
目录
一、 文档目的
本文以两个数据库表BBSModel、BBSPart为例,来描述三层架构下数据库访问层的实现及改进。
二、 词汇表
DB层:本文中的DB层指的是三层架构中的数据库访问层,由于该层中的类名多是以DB结尾,所以称为DB层。
DB类:DB层中,针对每一个数据库表而专门设置的类叫DB类,主要实现对该表的增删改查,类名以DB结尾。
DT层:用于存储数据库表结构数据的层,由于该层中类的类名多数以DT结尾,故得名。
DT类:用于存储某个数据库表结构数据的类,类名以DT结尾。
SQL类:用于存储某个数据库表操作的所有SQL语句的类,类名以SQL结尾。
SQL层:用于存储数据库表操作SQL语句的层,由于该层的类多数以SQL结尾,故得名。
三、 数据库表结构
1. BBSModel
名称 |
代码 |
类型 |
为空 |
备注 |
UID |
UID |
int |
N |
UID是主键 |
版式名称 |
BBSModelID |
Varchar(50) |
N |
|
版式中文名称 |
BBSModelName |
Varchar(20) |
N |
|
版式路径 |
BBSModelPath |
Varchar(50) |
N |
1个人会员2企业会员3专家会员 |
2. BBSPart
名称 |
代码 |
类型 |
为空 |
备注 |
UID |
UID |
Int(4) |
N |
UID是主键 |
版块名称 |
PartID |
Varchar(50) |
N |
|
版块中文名称 |
PartName |
Tinyint(1) |
N |
|
四、 DT层、DB层代码
DB层基类:
using System;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Data;
using Yingnet.Common;
using Yingnet.Common.Database;
using Yingnet.Utils;
using Yingnet.CRM.Common;
namespace Yingnet.CRM.DB
{
/// <summary>
/// BaseDB 的摘要说明。
/// </summary>
public class BaseDB : CommonBaseDB
{
public BaseDB(DBOperate dbOper) :base(dbOper)
{
}
}
}
1. BBSModel
DT层--- BbsmodelDT类:该类存储数据库表BBSModel的表结构数据。
using System;
namespace Yingnet.EMS.db.data
{
/// <summary>
/// BbsmodelDT的摘要说明。
/// </summary>
public class BbsmodelDT
{
public BbsmodelDT()
{
}
/// <summary>
///
/// </summary>
public smallint UID;
/// <summary>
/// 版式名称
/// </summary>
public string BBSModelID;
/// <summary>
/// 版式中文名称
/// </summary>
public string BBSModelName;
/// <summary>
/// 版式中文名称
/// </summary>
public string BBSModelPath;
}
}
DB层--- BbsmodelDB类:该类实现对数据库表BBSModel的增删改查的操作。
using System;
using System.Data;
using System.Collections;
using Yingnet.EMS.db.data;
using Yingnet.Common;
using Yingnet.Utils;
using Yingnet.Common.Database;
namespace Yingnet.EMS.db
{
/// <summary>
/// BbsmodelDB的摘要说明。
/// </summary>
public class BbsmodelDB : BaseDB
{
public BbsmodelDB(DBOperate oper) : base(oper)
{
}
/// <summary>
/// 添加一条记录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Add(BbsmodelDT detail)
{
int affected = 0;
string sql= "INSERT INTO BBSModel (UID,BBSModelID,BBSModelName,BBSModelPath) VALUES ("+ detail.UID+ ",'"+ StringUtils.ToSQL(detail.BBSModelID)+"'"+ ",'"+ StringUtils.ToSQL(detail.BBSModelName)+"'"+ ",'"+ StringUtils.ToSQL(detail.BBSModelPath)+"'"+")";
try
{
affected = ExecuteForInt(sql);
}
catch (Exception ex)
{
throw ex;
}
finally
{
}
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 修改一条纪录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Edit(BbsmodelDT detail)
{
int affected = 0;
string sql= "UPDATE BBSModel set UID="+ detail.UID+",BBSModelID='"+ StringUtils.ToSQL(detail.BBSModelID)+"'"+",BBSModelName='"+ StringUtils.ToSQL(detail.BBSModelName)+"'"+",BBSModelPath='"+ StringUtils.ToSQL(detail.BBSModelPath)+"'"+" where (UID="+ detail.UID+")";
try
{
affected = ExecuteForInt(sql);
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 删除一条纪录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Delete(smallint UID)
{
int affected = 0;
string sql= "DELETE FROM BBSModel where (UID="+ UID+")";
try
{
affected = ExecuteForInt(sql);
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 获取一条纪录
/// </summary>
public BbsmodelDT Get(smallint UID)
{
BbsmodelDT detail= new BbsmodelDT();
try
{
string sql= "select * from BBSModel where (UID="+ UID+")";
DataTable dt= this.ExecuteForDataTable(sql);
DataRow dr=null;
int rowCount= dt.Rows.Count;
if (rowCount>=0)
{
dr= dt.Rows[0];
detail.UID= Convert.ToInt16(dr["UID"]);
detail.BBSModelID= Convert.ToString(dr["BBSModelID"]);
detail.BBSModelName= Convert.ToString(dr["BBSModelName"]);
detail.BBSModelPath= Convert.ToString(dr["BBSModelPath"]);
}
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
return detail;
}
/// <summary>
/// 获取数据集
/// </summary>
public DataTable GetList()
{
DataTable dt= null;
try
{
string sql= "select * from BBSModel";
dt= this.ExecuteForDataTable(sql);
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
return dt;
}
}
}
2. BBSPart
DT层--- BbspartDT类:该类存储数据库表BBSPart的表结构数据。
using System;
namespace Yingnet.EMS.db.data
{
/// <summary>
/// BbspartDT的摘要说明。
/// </summary>
public class BbspartDT
{
public BbspartDT()
{
}
/// <summary>
///
/// </summary>
public int UID;
/// <summary>
///
/// </summary>
public string PartID;
/// <summary>
///
/// </summary>
public string PartName;
}
}
DB层--- BbspartDB:该类实现对数据库表BBSPart的增删改查的操作。
using System;
using System.Data;
using System.Collections;
using Yingnet.EMS.db.data;
using Yingnet.Common;
using Yingnet.Utils;
using Yingnet.Common.Database;
namespace Yingnet.EMS.db
{
/// <summary>
/// BbspartDB的摘要说明。
/// </summary>
public class BbspartDB : BaseDB
{
public BbspartDB(DBOperate oper) : base(oper)
{
}
/// <summary>
/// 添加一条记录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Add(BbspartDT detail)
{
int affected = 0;
string sql= "INSERT INTO BBSPart (UID,PartID,PartName) VALUES ("+ detail.UID+ ",'"+ StringUtils.ToSQL(detail.PartID)+"'"+ ",'"+ StringUtils.ToSQL(detail.PartName)+"'"+")";
try
{
affected = ExecuteForInt(sql);
}
catch (Exception ex)
{
throw ex;
}
finally
{
}
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 修改一条纪录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Edit(BbspartDT detail)
{
int affected = 0;
string sql= "UPDATE BBSPart set UID="+ detail.UID+",PartID='"+ StringUtils.ToSQL(detail.PartID)+"'"+",PartName='"+ StringUtils.ToSQL(detail.PartName)+"'"+" where (UID="+ detail.UID+")";
try
{
affected = ExecuteForInt(sql);
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 删除一条纪录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Delete(int UID)
{
int affected = 0;
string sql= "DELETE FROM BBSPart where (UID="+ UID+")";
try
{
affected = ExecuteForInt(sql);
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 获取一条纪录
/// </summary>
public BbspartDT Get(int UID)
{
BbspartDT detail= new BbspartDT();
try
{
string sql= "select * from BBSPart where (UID="+ UID+")";
DataTable dt= this.ExecuteForDataTable(sql);
DataRow dr=null;
int rowCount= dt.Rows.Count;
if (rowCount>=0)
{
dr= dt.Rows[0];
detail.UID= Convert.ToInt32(dr["UID"]);
detail.PartID= Convert.ToString(dr["PartID"]);
detail.PartName= Convert.ToString(dr["PartName"]);
}
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
return detail;
}
/// <summary>
/// 获取数据集
/// </summary>
public DataTable GetList()
{
DataTable dt= null;
try
{
string sql= "select * from BBSPart";
dt= this.ExecuteForDataTable(sql);
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
return dt;
}
}
}
五、 增删改的分析与改进
1. 分析
分析DB层中的类BbsmodelDB、BbspartDB可以得到:在这两个类中,Add、Edit、Delete这几个方法的处理思路是一样的,如下图:
图1:增删改的流程图
通过分析可知,可以从BbsmodelDB、BbspartDB中的Add、Edit、Delete几个方法抽象出一个通用的方法Execute,代码如下:
/// <summary>
/// 执行操作
/// </summary>
/// <param name="sql">SQL语句</param>
/// <returns>true 成功 false 失败</returns>
protected bool Execute(string sql)
{
int affected = ExecuteForInt(sql);
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
2. 改进
通过分析,可以改进DB层基类及BbsmodelDB、BbspartDB类如下:
DB层基类:
using System;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Data;
using Yingnet.Common;
using Yingnet.Common.Database;
using Yingnet.Utils;
using Yingnet.CRM.Common;
namespace Yingnet.CRM.DB
{
/// <summary>
/// BaseDB 的摘要说明。
/// </summary>
public class BaseDB : CommonBaseDB
{
/// <summary>
/// 执行操作
/// </summary>
/// <param name="sql">SQL语句</param>
/// <returns>true 成功 false 失败</returns>
protected bool Execute(string sql)
{
int affected = ExecuteForInt(sql);
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// 执行操作
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="parameters">参数数组</param>
/// <returns>true 成功 false 失败</returns>
protected bool Execute(string sql,IDataParameter[] parameters)
{
int affected = ExecuteForInt(sql,parameters);
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
public BaseDB(DBOperate dbOper) :base(dbOper)
{
}
}
}
BbsmodelDB类:
using System;
using System.Data;
using System.Collections;
using Yingnet.EMS.db.data;
using Yingnet.Common;
using Yingnet.Utils;
using Yingnet.Common.Database;
namespace Yingnet.EMS.db
{
/// <summary>
/// BbsmodelDB的摘要说明。
/// </summary>
public class BbsmodelDB : BaseDB
{
public BbsmodelDB(DBOperate oper) : base(oper)
{
}
/// <summary>
/// 添加一条记录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Add(BbsmodelDT detail)
{
int affected = 0;
string sql= "INSERT INTO BBSModel (UID,BBSModelID,BBSModelName,BBSModelPath) VALUES ("+ detail.UID+ ",'"+ StringUtils.ToSQL(detail.BBSModelID)+"'"+ ",'"+ StringUtils.ToSQL(detail.BBSModelName)+"'"+ ",'"+ StringUtils.ToSQL(detail.BBSModelPath)+"'"+")";
return Execute(sql);
}
/// <summary>
/// 修改一条纪录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Edit(BbsmodelDT detail)
{
int affected = 0;
string sql= "UPDATE BBSModel set UID="+ detail.UID+",BBSModelID='"+ StringUtils.ToSQL(detail.BBSModelID)+"'"+",BBSModelName='"+ StringUtils.ToSQL(detail.BBSModelName)+"'"+",BBSModelPath='"+ StringUtils.ToSQL(detail.BBSModelPath)+"'"+" where (UID="+ detail.UID+")";
return Execute(sql);
}
/// <summary>
/// 删除一条纪录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Delete(smallint UID)
{
int affected = 0;
string sql= "DELETE FROM BBSModel where (UID="+ UID+")";
return Execute(sql);
}
/// <summary>
/// 获取一条纪录
/// </summary>
public BbsmodelDT Get(smallint UID)
{
BbsmodelDT detail= new BbsmodelDT();
try
{
string sql= "select * from BBSModel where (UID="+ UID+")";
DataTable dt= this.ExecuteForDataTable(sql);
DataRow dr=null;
int rowCount= dt.Rows.Count;
if (rowCount>=0)
{
dr= dt.Rows[0];
detail.UID= Convert.ToInt16(dr["UID"]);
detail.BBSModelID= Convert.ToString(dr["BBSModelID"]);
detail.BBSModelName= Convert.ToString(dr["BBSModelName"]);
detail.BBSModelPath= Convert.ToString(dr["BBSModelPath"]);
}
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
return detail;
}
/// <summary>
/// 获取数据集
/// </summary>
public DataTable GetList()
{
DataTable dt= null;
try
{
string sql= "select * from BBSModel";
dt= this.ExecuteForDataTable(sql);
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
return dt;
}
}
}
BbspartDB类:
using System;
using System.Data;
using System.Collections;
using Yingnet.EMS.db.data;
using Yingnet.Common;
using Yingnet.Utils;
using Yingnet.Common.Database;
namespace Yingnet.EMS.db
{
/// <summary>
/// BbspartDB的摘要说明。
/// </summary>
public class BbspartDB : BaseDB
{
public BbspartDB(DBOperate oper) : base(oper)
{
}
/// <summary>
/// 添加一条记录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Add(BbspartDT detail)
{
int affected = 0;
string sql= "INSERT INTO BBSPart (UID,PartID,PartName) VALUES ("+ detail.UID+ ",'"+ StringUtils.ToSQL(detail.PartID)+"'"+ ",'"+ StringUtils.ToSQL(detail.PartName)+"'"+")";
return Execute(sql);
}
/// <summary>
/// 修改一条纪录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Edit(BbspartDT detail)
{
int affected = 0;
string sql= "UPDATE BBSPart set UID="+ detail.UID+",PartID='"+ StringUtils.ToSQL(detail.PartID)+"'"+",PartName='"+ StringUtils.ToSQL(detail.PartName)+"'"+" where (UID="+ detail.UID+")";
return Execute(sql);
}
/// <summary>
/// 删除一条纪录
/// </summary>
/// <param name="detail"></param>
/// <returns>true 成功 false 失败</returns>
public bool Delete(int UID)
{
int affected = 0;
string sql= "DELETE FROM BBSPart where (UID="+ UID+")";
return Execute(sql);
}
/// <summary>
/// 获取一条纪录
/// </summary>
public BbspartDT Get(int UID)
{
BbspartDT detail= new BbspartDT();
try
{
string sql= "select * from BBSPart where (UID="+ UID+")";
DataTable dt= this.ExecuteForDataTable(sql);
DataRow dr=null;
int rowCount= dt.Rows.Count;
if (rowCount>=0)
{
dr= dt.Rows[0];
detail.UID= Convert.ToInt32(dr["UID"]);
detail.PartID= Convert.ToString(dr["PartID"]);
detail.PartName= Convert.ToString(dr["PartName"]);
}
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
return detail;
}
/// <summary>
/// 获取数据集
/// </summary>
public DataTable GetList()
{
DataTable dt= null;
try
{
string sql= "select * from BBSPart";
dt= this.ExecuteForDataTable(sql);
}
catch(Exception ex)
{
throw ex;
}
finally
{
}
return dt;
}
}
}
六、 SQL语句的分析与改进
1. 分析
在DB类的每一个对数据库表中的操作中,都有一个SQL语句,这些SQL语句可以分解成一个SQL语句与一个相应的参数数组。
例如BbspartDB中Add方法的SQL语句:
string sql= "INSERT INTO BBSPart (UID,PartID,PartName) VALUES ("+ detail.UID+ ",'"+ StringUtils.ToSQL(detail.PartID)+"'"+ ",'"+ StringUtils.ToSQL(detail.PartName)+"'"+")";
可以分解成SQL语句:
"INSERT INTO BBSPart(PartID, Bbspart.PartName) VALUES(@PartID, @PartName)"
参数数组:
SqlParameter[] parameters =
{
new SqlParameter("@PartID",detail.PartID),
new SqlParameter("@PartName",detail.PartName)
};
每个DB类中,都会遇到增删改查。将各个方法中的sql语句分解成sql语句与参数数组,然后将这些sql语句与参数数组存储到一个特定的类中,则会增加代码的重用性。
引入的类可以命名为BbsmodelSQL和BbspartSQL。
每个SQL中都会有增删改查的sql语句与参数,所以,可以设置一个接口IBaseSQLable。
2. 改进
IBaseSQLable接口:提供各DB需要的SQL语句与参数数组。
using System;
using System.Data.SqlClient;
namespace Yingnet.EMS.db
{
/// <summary>
/// SQL类的接口。
/// </summary>
public interface IBaseSQLable
{
/// <summary>
/// 添加
/// </summary>
SqlParameter[] GetParameterADD(object detail);
/// <summary>
/// 修改
/// </summary>
SqlParameter[] GetParameterEDIT(object detail);
/// <summary>
/// 删除
/// </summary>
SqlParameter[] GetParameterDEL(object detail);
/// <summary>
/// 添加
/// </summary>
string SQL_ADD
{
get;
}
/// <summary>
/// 修改
/// </summary>
string SQL_EDIT
{
get;
}
/// <summary>
/// 删除
/// </summary>
string SQL_DEL
{
get;
}
}
}
BbsmodelSQL:提供BbsmodelDB类需要的SQL语句与参数数组。
using System;
using System.Data.SqlClient;
using Yingnet.EMS.db.data;
namespace Yingnet.EMS.db
{
/// <summary>
/// BbsmodelDB 的SQL类。
/// </summary>
public class BbsmodelSQL : IBaseSQLable
{
public BbsmodelSQL()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region 基本的增、删、改、查
#region 添加
/// <summary>
/// 添加记录的SQL语句
/// </summary>
public string SQL_ADD
{
get
{
return "INSERT INTO BBSModel (BBSModelID,BBSModelName,BBSModelPath) VALUES ( @BBSModelID,@BBSModelName,@BBSModelPath)";
}
}
/// <summary>
/// 参数数组
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>参数数组</returns>
public SqlParameter[] GetParameterADD(object detailDT)
{
BbsmodelDT detail = (BbsmodelDT)detailDT;
SqlParameter[] parameters =
{
new SqlParameter("@BBSModelID",detail.BBSModelID),
new SqlParameter("@BBSModelName",detail.BBSModelName),
new SqlParameter("@BBSModelPath",detail.BBSModelPath)
};
return parameters;
}
#endregion
#region 修改
/// <summary>
/// 修改记录的SQL语句
/// </summary>
public string SQL_EDIT
{
get
{
return "UPDATE BBSModel SET BBSModelID=@BBSModelID,BBSModelName=@BBSModelName,BBSModelPath=@BBSModelPath WHERE (UID=@UID)";
}
}
/// <summary>
/// 参数数组
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>参数数组</returns>
public SqlParameter[] GetParameterEDIT(object detailDT)
{
BbsmodelDT detail = (BbsmodelDT)detailDT;
SqlParameter[] parameters =
{
new SqlParameter("@UID",detail.UID),
new SqlParameter("@BBSModelID",detail.BBSModelID),
new SqlParameter("@BBSModelName",detail.BBSModelName),
new SqlParameter("@BBSModelPath",detail.BBSModelPath)
};
return parameters;
}
#endregion
#region 删除
/// <summary>
/// 删除记录的SQL语句
/// </summary>
public string SQL_DEL
{
get
{
return "DELETE FROM BBSModel WHERE (UID=@UID)";
}
}
/// <summary>
/// 参数数组
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>参数数组</returns>
public SqlParameter[] GetParameterDEL(object detailDT)
{
BbsmodelDT detail = (BbsmodelDT)detailDT;
SqlParameter[] parameters =
{
new SqlParameter("@UID",detail.UID)
};
return parameters;
}
#endregion
#region 获取一条记录
/// <summary>
/// 获取一条记录的SQL语句
/// </summary>
public string SQL_GET_DT
{
get
{
return "SELECT * FROM BBSModel WHERE (UID=@UID)";
}
}
/// <summary>
/// 参数数组
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>参数数组</returns>
public SqlParameter[] GetParameterGETDT(BbsmodelDT detail)
{
SqlParameter[] parameters =
{
new SqlParameter("@UID",detail.UID)
};
return parameters;
}
#endregion
#region 所有记录
/// <summary>
///所有记录的SQL语句
/// </summary>
public string SQL_LIST_ALL
{
get
{
return "SELECT BBSModel.UID,BBSModel.BBSModelID,BBSModel.BBSModelName,BBSModel.BBSModelPath FROM BBSModel “;
}
}
#endregion
#endregion
}
}
BbspartSQL:提供BbspartDB类需要的SQL语句与参数数组。
using System;
using System.Data.SqlClient;
using Yingnet.EMS.db.data;
namespace Yingnet.EMS.db
{
/// <summary>
/// BbspartDB 的SQL类。
/// </summary>
public class BbspartSQL : IBaseSQLable
{
public BbspartSQL()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region 基本的增、删、改、查
#region 添加
/// <summary>
/// 添加记录的SQL语句
/// </summary>
public string SQL_ADD
{
get
{
return "INSERT INTO BBSPart (PartID,PartName) VALUES ( @PartID,@PartName)";
}
}
/// <summary>
/// 参数数组
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>参数数组</returns>
public SqlParameter[] GetParameterADD(object detailDT)
{
BbspartDT detail = (BbspartDT)detailDT;
SqlParameter[] parameters =
{
new SqlParameter("@PartID",detail.PartID),
new SqlParameter("@PartName",detail.PartName)
};
return parameters;
}
#endregion
#region 修改
/// <summary>
/// 修改记录的SQL语句
/// </summary>
public string SQL_EDIT
{
get
{
return "UPDATE BBSPart SET PartID=@PartID,PartName=@PartName WHERE (UID=@UID)";
}
}
/// <summary>
/// 参数数组
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>参数数组</returns>
public SqlParameter[] GetParameterEDIT(object detailDT)
{
BbspartDT detail = (BbspartDT)detailDT;
SqlParameter[] parameters =
{
new SqlParameter("@UID",detail.UID),
new SqlParameter("@PartID",detail.PartID),
new SqlParameter("@PartName",detail.PartName)
};
return parameters;
}
#endregion
#region 删除
/// <summary>
/// 删除记录的SQL语句
/// </summary>
public string SQL_DEL
{
get
{
return "DELETE FROM BBSPart WHERE (UID=@UID)";
}
}
/// <summary>
/// 参数数组
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>参数数组</returns>
public SqlParameter[] GetParameterDEL(object detailDT)
{
BbspartDT detail = (BbspartDT)detailDT;
SqlParameter[] parameters =
{
new SqlParameter("@UID",detail.UID)
};
return parameters;
}
#endregion
#region 获取一条记录
/// <summary>
/// 获取一条记录的SQL语句
/// </summary>
public string SQL_GET_DT
{
get
{
return "SELECT * FROM BBSPart WHERE (UID=@UID)";
}
}
/// <summary>
/// 参数数组
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>参数数组</returns>
public SqlParameter[] GetParameterGETDT(BbspartDT detail)
{
SqlParameter[] parameters =
{
new SqlParameter("@UID",detail.UID)
};
return parameters;
}
#endregion
#region 所有记录
/// <summary>
///所有记录的SQL语句
/// </summary>
public string SQL_LIST_ALL
{
get
{
return "SELECT BBSPart.UID,BBSPart.PartID,BBSPart.PartName FROM BBSPart ";
}
}
#endregion
#endregion
}
}
引入SQL类后,就可以将DB类中的Add、Edit、Delete放到BaseDB类中了。
需要对DB中的类作如下修改:
BaseDB:
using System;
using System.Data;
using Yingnet.Common;
using Yingnet.Common.Database;
namespace Yingnet.EMS.db
{
/// <summary>
/// 数据访问层的基类。
/// </summary>
public class BaseDB : CommonBaseDB
{
protected IBaseSQLable parSql ;
public BaseDB(DBOperate dbOper) : base(dbOper)
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region 基本的增、删、改、查
#region 添加
/// <summary>
/// 添加一条新记录
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>true 成功 false 失败</returns>
public bool Add(object detail)
{
return Execute(parSql.SQL_ADD,parSql.GetParameterADD(detail));
}
#endregion
#region 修改
/// <summary>
/// 修改一条纪录
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>true 成功 false 失败</returns>
public bool Edit(object detail)
{
return Execute(parSql.SQL_EDIT,parSql.GetParameterEDIT(detail));
}
#endregion
#region 删除
/// <summary>
/// 删除一条纪录
/// </summary>
/// <param name="detail">主健</param>
/// <returns>true 成功 false 失败</returns>
public bool Delete(object detail)
{
return Execute(parSql.SQL_DEL,parSql.GetParameterDEL(detail));
}
#endregion
#endregion
#region 执行操作
/// <summary>
/// 执行操作
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="parameters">参数数组</param>
/// <returns>true 成功 false 失败</returns>
protected bool Execute(string sql,IDataParameter[] parameters)
{
int affected = ExecuteForInt(sql,parameters);
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
#endregion
}
}
BbsmodelDB:
using System;
using System.Collections;
using System.Data;
using Yingnet.Common;
using Yingnet.Common.Database;
using Yingnet.Utils;
using Yingnet.EMS.db.data;
namespace Yingnet.EMS.db
{
/// <summary>
/// BbsmodelDB的DB类。
/// </summary>
public class BbsmodelDB : BaseDB
{
private BbsmodelSQL sql = new BbsmodelSQL();
public BbsmodelDB(DBOperate oper) : base(oper)
{
parSql = (IBaseSQLable)sql;
}
#region 获取一条记录
/// <summary>
/// 获取一条记录
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>一条记录</returns>
public BbsmodelDT Get(BbsmodelDT detail)
{
BbsmodelDT detailDT = new BbsmodelDT();
DataTable dt = this.ExecuteForDataTable(sql.SQL_GET_DT,sql.GetParameterGETDT(detail));
int rowCount= dt.Rows.Count;
if (rowCount>=0)
{
dr= dt.Rows[0];
detail.UID= Convert.ToInt16(dr["UID"]);
detail.BBSModelID= Convert.ToString(dr["BBSModelID"]);
detail.BBSModelName= Convert.ToString(dr["BBSModelName"]);
detail.BBSModelPath= Convert.ToString(dr["BBSModelPath"]);
}
return detailDT;
}
#endregion
}
}
BbspartDB:
using System;
using System.Collections;
using System.Data;
using Yingnet.Common;
using Yingnet.Common.Database;
using Yingnet.Utils;
using Yingnet.EMS.db.data;
namespace Yingnet.EMS.db
{
/// <summary>
/// BbspartDB的DB类。
/// </summary>
public class BbspartDB : BaseDB
{
private BbspartSQL sql = new BbspartSQL();
public BbspartDB(DBOperate oper) : base(oper)
{
parSql = (IBaseSQLable)sql;
}
#region 获取一条记录
/// <summary>
/// 获取一条记录
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>一条记录</returns>
public BbspartDT Get(BbspartDT detail)
{
BbspartDT detailDT = new BbspartDT();
DataTable dt = this.ExecuteForDataTable(sql.SQL_GET_DT,sql.GetParameterGETDT(detail));
int rowCount= dt.Rows.Count;
if (rowCount>=0)
{
dr= dt.Rows[0];
detail.UID= Convert.ToInt32(dr["UID"]);
detail.PartID= Convert.ToString(dr["PartID"]);
detail.PartName= Convert.ToString(dr["PartName"]);
}
return detailDT;
}
#endregion
}
}
七、 对Get方法的分析与改进
1. 分析
现在把Add、Edit、Delet都放入到DB层的基类BaseDB中,只有Get方法与具体的DB类有关了。
能不能把Get放入DB层的基类BaseDB类中呢?如果能把Get方法放入基类,则普通的DB类就可以去掉了。
下面是BbspartDB中的Get方法:
/// <summary>
/// 获取一条记录
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>一条记录</returns>
public BbspartDT Get(BbspartDT detail)
{
BbspartDT detailDT = new BbspartDT();
DataTable dt = this.ExecuteForDataTable(sql.SQL_GET_DT,sql.GetParameterGETDT(detail));
int rowCount= dt.Rows.Count;
if (rowCount>=0)
{
dr= dt.Rows[0];
detail.UID= Convert.ToInt32(dr["UID"]);
detail.PartID= Convert.ToString(dr["PartID"]);
detail.PartName= Convert.ToString(dr["PartName"]);
}
return detailDT;
}
各个DB类中的Get方法,有两个地方明显不同:
1:返回值类型不同。BbspartDB类中,Get方法返回的是BbspartDT对象。BbsmodelDB类中,Get方法返回的是BbsmodelDT对象。
2:给DT对象赋值的语句不同。
BbsmodelDB类Get方法中的赋值代码是:
dr= dt.Rows[0];
detail.UID= Convert.ToInt16(dr["UID"]);
detail.BBSModelID= Convert.ToString(dr["BBSModelID"]);
detail.BBSModelName= Convert.ToString(dr["BBSModelName"]);
detail.BBSModelPath= Convert.ToString(dr["BBSModelPath"]);
而BbspartDB类Get方法中的赋值代码是:
dr= dt.Rows[0];
detail.UID= Convert.ToInt32(dr["UID"]);
detail.PartID= Convert.ToString(dr["PartID"]);
detail.PartName= Convert.ToString(dr["PartName"]);
对于返回值类型不同的问题,可以采用装箱拆箱的方法来实现,让所有的Get方法都返回object类型就可以了。
而对赋值代码,就不能这样处理,而且还有一个问题。例如,在BbspartDB类Get方法中的赋值代码中,如果dr["PartID"]为空,则如何处理?
现在,需要一个能给所有DB类中Get方法赋值,又能自动判断数据是否为空的类。CBO就是这样一个类。
2. 改进
首先,需要一个类来处理空值,命名为Null。
Null类:处理空值。
using System;
using System.Reflection;
namespace WebApplication1
{
/// <summary>
/// 对空值的处理。
/// </summary>
public class Null
{
public Null()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
// 各类型的空值表示值
public static short NullShort
{
get
{
return -1;
}
}
public static int NullInteger
{
get
{
return -1;
}
}
public static Single NullSingle
{
get
{
return Single.MinValue;
}
}
public static double NullDouble
{
get
{
return double.MinValue;
}
}
public static decimal NullDecimal
{
get
{
return decimal.MinValue;
}
}
public static DateTime NullDate
{
get
{
return DateTime.MinValue;
}
}
public static string NullString
{
get
{
return "";
}
}
public static bool NullBoolean
{
get
{
return false;
}
}
public static Guid NullGuid
{
get
{
return Guid.Empty;
}
}
/// <summary>
/// 根据类型设置空值。如果objValue值不为空,返回。
/// </summary>
/// <param name="objValue"></param>
/// <param name="objField"></param>
/// <returns></returns>
public static object SetNull(object objValue, object objField)
{
object ret;
if (objValue is DBNull)
{
if (objField is short)
{
ret = NullShort;
}
else if (objField is int)
{
ret = NullInteger;
}
else if (objField is Single)
{
ret = NullSingle;
}
else if (objField is double)
{
ret = NullDouble;
}
else if (objField is decimal)
{
ret = NullDecimal;
}
else if (objField is DateTime)
{
ret = NullDate;
}
else if (objField is string)
{
ret = NullString;
}
else if (objField is bool)
{
ret = NullBoolean;
}
else if (objField is Guid)
{
ret = NullGuid;
}
else
{
ret = null;
}
}
else
{
ret = objValue;
}
return ret;
}
/// <summary>
/// 根据PropertyInfo来设计空值。
/// </summary>
/// <param name="objPropertyInfo"></param>
/// <returns></returns>
public static object SetNull(PropertyInfo objPropertyInfo)
{
object ret;
switch (objPropertyInfo.PropertyType.ToString())
{
case "System.Int16":
ret = NullShort;
break;
case "System.Int32":
case "System.Int64":
ret = NullInteger;
break;
case "System.Single":
ret = NullSingle;
break;
case "System.Double":
ret = NullDouble;
break;
case "System.Decimal":
ret = NullDecimal;
break;
case "System.DateTime":
ret = NullDate;
break;
case "System.String":
case "System.Char":
ret = NullString;
break;
case "System.Boolean":
ret = NullBoolean;
break;
case "System.Guid":
ret = NullGuid;
break;
default:
Type pType = objPropertyInfo.PropertyType;
if (pType.BaseType.Equals(typeof(System.Enum)))
{
Array objEnumValues = Enum.GetValues(pType);
Array.Sort(objEnumValues);
ret = Enum.ToObject(pType, objEnumValues.GetValue(0));
}
else
{
ret = null;
}
break;
}
return ret;
}
/// <summary>
/// 根据FieldInfo来设计空值。
/// </summary>
/// <param name="objFieldInfo"></param>
/// <returns></returns>
public static object SetNull(FieldInfo objFieldInfo)
{
object ret;
switch (objFieldInfo.FieldType.ToString())
{
case "System.Int16":
ret = NullShort;
break;
case "System.Int32":
case "System.Int64":
ret = NullInteger;
break;
case "System.Single":
ret = NullSingle;
break;
case "System.Double":
ret = NullDouble;
break;
case "System.Decimal":
ret = NullDecimal;
break;
case "System.DateTime":
ret = NullDate;
break;
case "System.String":
case "System.Char":
ret = NullString;
break;
case "System.Boolean":
ret = NullBoolean;
break;
case "System.Guid":
ret = NullGuid;
break;
default:
Type pType = objFieldInfo.FieldType;
if (pType.BaseType.Equals(typeof(System.Enum)))
{
Array objEnumValues = Enum.GetValues(pType);
Array.Sort(objEnumValues);
ret = Enum.ToObject(pType, objEnumValues.GetValue(0));
}
else
{
ret = null;
}
break;
}
return ret;
}
/// <summary>
/// 根据数据类型,取得空值。
/// 如果objField为空,则返回objDBNull。
/// </summary>
/// <param name="objField"></param>
/// <param name="objDBNull"></param>
/// <returns></returns>
public static object GetNull(object objField, object objDBNull)
{
object ret = objField;
if (objField == null)
{
ret = objDBNull;
}
else if (objField is short)
{
if (Convert.ToInt16(objField) == NullShort)
{
ret = objDBNull;
}
}
else if (objField is int)
{
if (Convert.ToInt32(objField) == NullInteger)
{
ret = objDBNull;
}
}
else if (objField is Single)
{
if (Convert.ToSingle(objField) == NullSingle)
{
ret = objDBNull;
}
}
else if (objField is double)
{
if (Convert.ToDouble(objField) == NullDouble)
{
ret = objDBNull;
}
}
else if (objField is decimal)
{
if (Convert.ToDecimal(objField) == NullDecimal)
{
ret = objDBNull;
}
}
else if (objField is DateTime)
{
if (Convert.ToDateTime(objField) == NullDate.Date)
{
ret = objDBNull;
}
}
else if (objField is string)
{
if (objField == null)
{
ret = objDBNull;
}
}
else if (objField is bool)
{
if (Convert.ToBoolean(objField) == NullBoolean)
{
ret = objDBNull;
}
}
else if (objField is Guid)
{
if (((Guid)objField).Equals(NullGuid))
{
ret = objDBNull;
}
}
return ret;
}
/// <summary>
/// 判断某个值是否为空值
/// </summary>
/// <param name="objField"></param>
/// <returns></returns>
public static bool IsNull(object objField)
{
bool ret;
if (objField != null)
{
if (objField is int)
{
ret = objField.Equals(NullInteger);
}
else if (objField is Single)
{
ret = objField.Equals(NullSingle);
}
else if (objField is double)
{
ret = objField.Equals(NullDouble);
}
else if (objField is decimal)
{
ret = objField.Equals(NullDecimal);
}
else if (objField is DateTime)
{
DateTime objDate = Convert.ToDateTime(objField);
ret = objDate.Equals(NullInteger);
}
else if (objField is string)
{
ret = objField.Equals(NullString);
}
else if (objField is bool)
{
ret = objField.Equals(NullBoolean);
}
else if (objField is Guid)
{
ret = objField.Equals(NullGuid);
}
else
{
ret = false;
}
}
else
{
ret = true;
}
return ret;
}
}
}
类CBO:给对象赋值。
using System;
using System.Data;
using System.Web.Caching;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using System.Text;
using System.IO;
using System.Collections;
using Microsoft.VisualBasic;
namespace WebApplication1
{
/// <summary>
/// 根据类型关键字取得相应的对象。
/// 为什么没有用DataTable或DataSet来填充对象的方法。
/// </summary>
public class CBO
{
public CBO()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// 返回存储某类型的所有属性的集合。
/// </summary>
/// <param name="objType">类型(类、接口、枚举等)</param>
/// <returns>属性集合</returns>
public static ArrayList GetPropertyInfo(Type objType)
{
// 存储属性的集合,并试图从缓存中查找关于objType类型的属性,以期填充类型。
ArrayList objProperties = (ArrayList)DataCache.GetCache(objType.FullName);
// 如果属性集合为空
if (objProperties == null)
{
// 初始化集合
objProperties = new ArrayList();
// PropertyInfo:发现属性的特性并提供对属性元数据的访问。
// GetProperties:返回当前Type的所有公共属性。
foreach (PropertyInfo objProperty in objType.GetProperties())
{
// 用属性填充集合
objProperties.Add(objProperty);
}
}
// 返回类型集合
return objProperties;
}
/// <summary>
/// 返回dr属性字段索引的数组。
/// </summary>
/// <param name="objProperties">属性数组[存储着dr的列字段名称的属性]</param>
/// <param name="dr"></param>
/// <returns>字段索引的数组</returns>
public static int[] GetOrdinals(ArrayList objProperties, IDataReader dr)
{
// 形成对应属性集合的整合数组
int[] arrOrdinals = new int[objProperties.Count];
if (dr != null)
{
int count = objProperties.Count;
// 遍历每一个属性
for (int intProperty = 0; intProperty < count; intProperty++)
{
arrOrdinals[intProperty] = -1;
try
{
// 设置该属性对应dr中的索引号, 如果没有,设置为-1
PropertyInfo propertyInfo = (PropertyInfo)objProperties[intProperty];
// GetOrdinal:返回命名字段的索引。
// propertyInfo.Name:获取此成员的名称。
// 该行试图返回字段名称为propertyInfo.Name的DataReader的列索引
arrOrdinals[intProperty] = dr.GetOrdinal(propertyInfo.Name);
}
catch
{
}
}
}
// 返回命名字段索引的数组
return arrOrdinals;
}
/// <summary>
/// 给objType类型的对象属性逐个赋值并返回。
/// </summary>
/// <param name="objType">对象类型</param>
/// <param name="dr">存储记录的DataReader</param>
/// <param name="objProperties">属性集合</param>
/// <param name="arrOrdinals">索引集合</param>
/// <returns>objType类型对象</returns>
private static object CreateObject(Type objType, IDataReader dr, ArrayList objProperties, int[] arrOrdinals)
{
// 在这儿声明属性对象,估计是为了性能考虑
PropertyInfo objPropertyInfo;
object objValue;
Type objPropertyType = null;
// 创建objType类型的对象
object objObject = Activator.CreateInstance(objType);
int count = objProperties.Count;
for (int intProperty = 0; intProperty < count; intProperty++)
{
// 取得第intProperty个属性
objPropertyInfo = (PropertyInfo)objProperties[intProperty];
// 如果该属性允许写入
if (objPropertyInfo.CanWrite)
{
// 将objValue设置为空 根据objPropertyInfo.PropertyType值来取得空值
objValue = Null.SetNull(objPropertyInfo);
// 如果索引大于-1
if (arrOrdinals[intProperty] != -1)
{
// 判断dr的第arrOrdinals[intProperty]格元素是空
if (Information.IsDBNull(dr.GetValue(arrOrdinals[intProperty])))
{
// 将给定对象的属性值设置为给定值[即相应的空值]
objPropertyInfo.SetValue(objObject, objValue, null);
}
// 如果不是空
else
{
try
{
// 将给定对象的属性值设置为给定值
objPropertyInfo.SetValue(objObject, dr.GetValue(arrOrdinals[intProperty]), null);
}
catch
{
// 如果设置不成功
try
{
// 取得相应数据类型
objPropertyType = objPropertyInfo.PropertyType;
// BaseType:获取当前 System.Type 直接从中继承的类型
// 如果类型是枚举
if (objPropertyType.BaseType.Equals(typeof(System.Enum)))
{
// 判断dr的第arrOrdinals[intProperty]格元素是不是数字
if (Information.IsNumeric(dr.GetValue(arrOrdinals[intProperty])))
{
// 将给定对象的属性值设置为给定值 即第Convert.ToInt32(dr.GetValue(arrOrdinals[intProperty])个枚举值
((PropertyInfo)objProperties[intProperty]).SetValue(objObject, System.Enum.ToObject(objPropertyType, Convert.ToInt32(dr.GetValue(arrOrdinals[intProperty]))), null);
}
else
{
// 将给定对象的属性值设置为给定值
((PropertyInfo)objProperties[intProperty]).SetValue(objObject, System.Enum.ToObject(objPropertyType,dr.GetValue(arrOrdinals[intProperty])), null);
}
}
// 如果不是枚举类型
else
{
objPropertyInfo.SetValue(objObject, Convert.ChangeType(dr.GetValue(arrOrdinals[intProperty]), objPropertyType), null);
}
}
catch
{
// 将给定对象的属性值设置为给定值
objPropertyInfo.SetValue(objObject, Convert.ChangeType(dr.GetValue(arrOrdinals[intProperty]), objPropertyType), null);
}
}
}
}
}
}
// 返回objObject对象
return objObject;
}
/// <summary>
/// 用dr填充一个objType对象,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <returns>objType对象</returns>
public static object FillObject(IDataReader dr, Type objType)
{
return FillObject(dr, objType, true);
}
/// <summary>
/// 用dr填充一个objType对象,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <param name="ManageDataReader"></param>
/// <returns>objType对象</returns>
public static object FillObject(IDataReader dr, Type objType, bool ManageDataReader)
{
object objFillObject;
int intProperty;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得属性集合
ArrayList objProperties = GetPropertyInfo(objType);
// GetOrdinals:返回dr属性字段索引的数组。
// 返回索引数组
int[] arrOrdinals = GetOrdinals(objProperties, dr);
bool Continue = true;
// 要不要继续,如果dr不到最后,继续
if (ManageDataReader)
{
Continue = false;
if (dr.Read())
{
Continue = true;
}
}
if (Continue)
{
// CreateObject:给objType类型的对象逐个赋值并返回。
objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals);
}
else
{
objFillObject = null;
}
if (ManageDataReader)
{
if (dr != null)
{
dr.Close();
}
}
// 返回对象
return objFillObject;
}
/// <summary>
/// 用dr填充一个objType对象数组,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <returns>对象数组</returns>
public static ArrayList FillConllection(IDataReader dr, Type objType)
{
// 一个集合
ArrayList objFillCollection = new ArrayList();
object objFillObject;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得objType类/接口的属性集合
ArrayList objProperties = GetPropertyInfo(objType);
// GetOrdinals:返回dr属性字段索引的数组。
// 返回索引数组
int[] arrOrdinals = GetOrdinals(objProperties, dr);
// 生成多个objType对象
while(dr.Read())
{
objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals);
objFillCollection.Add(objFillObject);
}
if (dr != null)
{
dr.Close();
}
// 返回对象数组
return objFillCollection;
}
/// <summary>
/// 用dr填充一个IList,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <param name="objToFill">IList</param>
/// <returns>IList</returns>
public static IList FillCollection(IDataReader dr, Type objType, IList objToFill)
{
object objFillObject;
int intProperty;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得objType类/接口的属性集合
ArrayList objProperties = GetPropertyInfo(objType);
// GetOrdinals:返回dr属性字段索引的数组。
// 返回索引数组
int[] arrOrdinals = GetOrdinals(objProperties, dr);
// 生成多个objType对象
while (dr.Read())
{
objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals);
objToFill.Add(objFillObject);
}
if (dr != null)
{
dr.Close();
}
// 返回IList
return objToFill;
}
/// <summary>
/// 给objType类型的对象赋初始值[空值]。
/// </summary>
/// <param name="objObject">赋值对象</param>
/// <param name="objType">对象类型</param>
/// <returns>赋初始值的对象</returns>
public static object InitializeObject(object objObject, Type objType)
{
PropertyInfo objPropertyInfo;
object objValue;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得objType类/接口的属性集合
ArrayList objProperties = GetPropertyInfo(objType);
// 依次赋值
for (int intProperty = 0; intProperty < objProperties.Count; intProperty++)
{
// 取得第intProperty个属性
objPropertyInfo = (PropertyInfo)objProperties[intProperty];
// 如果该属性允许写入
if (objPropertyInfo.CanWrite)
{
// 将objValue设置为空 根据objPropertyInfo.PropertyType值
objValue = Null.SetNull(objPropertyInfo);
// 将给定对象的属性值设置为给定值
objPropertyInfo.SetValue(objObject, objValue, null);
}
}
// 返回对象
return objObject;
}
public static XmlDocument Serialize(object objObject)
{
// 将对象序列化到 XML 文档中和从 XML 文档中反序列化对象。System.Xml.Serialization.XmlSerializer 使您得以控制如何将对象编码到 XML 中。
XmlSerializer objXmlSerializer = new XmlSerializer(objObject.GetType());
StringBuilder objStringBuilder = new StringBuilder();
// 表示可以编写一个有序字符系列的编写器。
TextWriter objTextWriter = new StringWriter(objStringBuilder);
// 使用指定的 System.Xml.XmlWriter 序列化指定的 System.Object 并将 XML 文档写入文件,从而引用指定的命名空间。
objXmlSerializer.Serialize(objTextWriter, objObject);
// 实现从字符串进行读取的 System.IO.TextReader。
StringReader objStringReader = new StringReader(objTextWriter.ToString());
DataSet objDataSet = new DataSet();
// 将数据读入到DataSet中
objDataSet.ReadXml(objStringReader);
XmlDocument xmlSerializedObject = new XmlDocument();
// LoadXml:从指定的字符串加载 XML 文档。
// GetXml:返回存储在 System.Data.DataSet 中的数据的 XML 表示形式
// 加载DataSet中的数据
xmlSerializedObject.LoadXml(objDataSet.GetXml());
return xmlSerializedObject;
}
public static object CloneObject(object ObjectToClone)
{
try
{
// 创建一个与ObjectToClone类型相同的对象
object newObject = Reflection.CreateObject(ObjectToClone.GetType().AssemblyQualifiedName, ObjectToClone.GetType().AssemblyQualifiedName);
// 取得newObject对象类型的属性集合
ArrayList props = GetPropertyInfo(newObject.GetType());
// 取得ObjectToClone对象类型的属性集合
ArrayList cloneArr = GetPropertyInfo(ObjectToClone.GetType());
// 取得属性的数量
int count = cloneArr.Count;
for (int i = 0; i < count; i++)
{
// 取得第i个属性对象
PropertyInfo p = (PropertyInfo)cloneArr[i];
// GetInterface:当在派生类中重写时,搜索指定接口,指定是否要执行区分大小写的搜索。
Type ICloneType = p.PropertyType.GetInterface("ICloneable", true);
// 如果属性可以写入
if (((PropertyInfo)props[i]).CanWrite)
{
// 如果类型不为空
if (ICloneType != null)
{
ICloneable IClone = (ICloneable)p.GetValue(ObjectToClone, null);
((PropertyInfo)props[i]).SetValue(newObject, IClone.Clone(), null);
}
else
{
((PropertyInfo)props[i]).SetValue(newObject, p.GetValue(ObjectToClone, null), null);
}
Type IEnumerableType = p.PropertyType.GetInterface("IEnumerable", true);
if (IEnumerableType != null)
{
IEnumerable IEnum = (IEnumerable)p.GetValue(ObjectToClone, null);
Type IListType = ((PropertyInfo)props[i]).PropertyType.GetInterface("IList", true);
Type IDicType = ((PropertyInfo)props[i]).PropertyType.GetInterface("IDictionary", true);
int j = 0;
if (IListType != null)
{
IList list = (IList)((PropertyInfo)props[i]).GetValue(newObject, null);
foreach (object obj in IEnum)
{
ICloneType = obj.GetType().GetInterface("ICloneable", true);
if (ICloneType != null)
{
ICloneable tmpClone = (ICloneable)obj;
list[j] = tmpClone.Clone();
j += 1;
}
}
}
else
{
if (IDicType != null)
{
IDictionary dic = (IDictionary)((PropertyInfo)props[i]).GetValue(newObject, null);
j = 0;
foreach(DictionaryEntry de in IEnum)
{
ICloneType = de.Value.GetType().GetInterface("ICloneable", true);
if (ICloneType != null)
{
ICloneable tmpClone = (ICloneable)de.Value;
}
j += 1;
}
}
}
}
else
{
}
}
}
return newObject;
}
catch (Exception exc)
{
Reflection.LogException(exc);
return null;
}
}
}
}
有了Null类与CBO类,就可以把Get方法放入DB基类BaseDB中了。
BaseDB类:
using System;
using System.Data;
using Yingnet.Common;
using Yingnet.Common.Database;
namespace Yingnet.EMS.db
{
/// <summary>
/// 数据访问层的基类。
/// </summary>
public class BaseDB : CommonBaseDB
{
protected IBaseSQLable parSql ;
public BaseDB(DBOperate dbOper) : base(dbOper)
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region 基本的增、删、改、查
#region 添加
/// <summary>
/// 添加一条新记录
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>true 成功 false 失败</returns>
public bool Add(object detail)
{
return Execute(parSql.SQL_ADD,parSql.GetParameterADD(detail));
}
#endregion
#region 修改
/// <summary>
/// 修改一条纪录
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>true 成功 false 失败</returns>
public bool Edit(object detail)
{
return Execute(parSql.SQL_EDIT,parSql.GetParameterEDIT(detail));
}
#endregion
#region 删除
/// <summary>
/// 删除一条纪录
/// </summary>
/// <param name="detail">主健</param>
/// <returns>true 成功 false 失败</returns>
public bool Delete(object detail)
{
return Execute(parSql.SQL_DEL,parSql.GetParameterDEL(detail));
}
#endregion
/// <summary>
/// 取得一条记录。
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>一条记录</returns>
public object Get(object detail)
{
IBaseSQLable sql = GetBaseSQL(detail);
IDataReader read = this.ExecuteForDataReader(sql.SQL_GET_DT, sql.GetParameterGETDT(detail));
return CBO.FillObject(read, detail.GetType(), true);
}
#endregion
#region 执行操作
/// <summary>
/// 执行操作
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="parameters">参数数组</param>
/// <returns>true 成功 false 失败</returns>
protected bool Execute(string sql,IDataParameter[] parameters)
{
int affected = ExecuteForInt(sql,parameters);
if (affected == 1)
{
return true;
}
else
{
return false;
}
}
#endregion
}
}
改进后的DB类BbsmodelDB、BBSPartDB如下。
BbsmodelDB:
using System;
using System.Collections;
using System.Data;
using Yingnet.Common;
using Yingnet.Common.Database;
using Yingnet.Utils;
using Yingnet.EMS.db.data;
namespace Yingnet.EMS.db
{
/// <summary>
/// BbsmodelDB的DB类。
/// </summary>
public class BbsmodelDB : BaseDB
{
private BbsmodelSQL sql = new BbsmodelSQL();
public BbsmodelDB(DBOperate oper) : base(oper)
{
parSql = (IBaseSQLable)sql;
}
}
}
BBSPartDB:
using System;
using System.Collections;
using System.Data;
using Yingnet.Common;
using Yingnet.Common.Database;
using Yingnet.Utils;
using Yingnet.EMS.db.data;
namespace Yingnet.EMS.db
{
/// <summary>
/// BbspartDB的DB类。
/// </summary>
public class BbspartDB : BaseDB
{
private BbspartSQL sql = new BbspartSQL();
public BbspartDB(DBOperate oper) : base(oper)
{
parSql = (IBaseSQLable)sql;
}
}
}
八、 对BaseDB的分析与改进
1. 分析
现在,对数据库主要的操作都在BaseDB中了。但是,还必须要DB类,因为需要根据DB类来取得不同的SQL类。
如果要想彻底去掉DB类,可以根据每个方法的参数不同来取得不同的SQL类。
2. 改进
类ReadSQL中的方法GetSqlByDT可以根据不同参数取得不同SQL对象。
using System;
using System.Configuration;
using Xumingxsh.DB.SQL;
namespace Xumingxsh.DB
{
/// <summary>
/// ReadSQL 的摘要说明。
/// </summary>
public class ReadSQL
{
public ReadSQL()
{
}
#region 根据对象类型取得SQL类型
public static IBaseSQLable GetSqlByDT(object obj)
{
if (obj.GetType().ToString().Equals("Yingnet.EMS.db.data.BbsmodelDT"))
{
return BbsmodelSQL;
}
else if (obj.GetType().ToString().Equals("Yingnet.EMS.db.data.BbspartDT"))
{
return BbspartSQL;
}
else
{
return null;
}
}
#endregion
}
}
其实,我们可以把参数类型与SQL类的对应关系添加到配置文件中,这样,两种对应关系就可以通过配置文件来配置了。
最后的BaseDB为:
using System;
using System.Data;
using System.Collections;
using DOCNET.Common;
using DOCNET.Common.Database;
using EMSXUMR.DB.SQL;
using Xumingxsh.DB.DataFeild;
namespace Xumingxsh.DB
{
/// <summary>
/// 数据访问层物理表操作类的基类,实现数据访问层物理表操作类中的公用方法
/// ,如添加、删除、修改记录等。
/// </summary>
public class BaseDB : CommonBaseDB
{
public BaseDB(DBOperate dbOper) : base(dbOper)
{
//
// TODO : 在此处添加构造函数逻辑
//
}
/// <summary>
/// 添加一条新记录。
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>true 成功 false 失败</returns>
public bool Add(object detail)
{
return Execute(detail, OperType.ADD);
}
/// <summary>
/// 修改一条纪录。
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>true 成功 false 失败</returns>
public bool Edit(object detail)
{
return Execute(detail, OperType.EDIT);
}
/// <summary>
/// 删除一条纪录。
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>true 成功 false 失败</returns>
public bool Delete(object detail)
{
return Execute(detail, OperType.DEL);
}
/// <summary>
/// 取得一条记录。
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>一条记录</returns>
public object Get(object detail)
{
IBaseSQLable sql = GetBaseSQL(detail);
IDataReader read = this.ExecuteForDataReader(sql.SQL_GET_DT, sql.GetParameterGETDT(detail));
return CBO.FillObject(read, detail.GetType(), true);
}
/// <summary>
/// 所有记录。
/// </summary>
/// <returns>一条记录</returns>
/// <returns>所有记录列表</returns>
public DataTable GetListAll(object detail)
{
IBaseSQLable sql = ReadSQL.GetSqlByDT(detail);
return ExecuteForDataTable(sql.SQL_LIST_ALL);
}
/// <summary>
/// 所有记录。
/// </summary>
/// <returns>一条记录</returns>
/// <returns>所有记录集合</returns>
public ArrayList GetListAllArrayList(object detail)
{
IBaseSQLable sql = ReadSQL.GetSqlByDT(detail);
IDataReader dr = ExecuteForDataReader(sql.SQL_LIST_ALL);
return CBO.FillConllection(dr, detail.GetType());
}
/// <summary>
/// 所有记录。
/// </summary>
/// <returns>一条记录</returns>
/// <param name="detail">返回的集合</param>
/// <returns>返回的集合</returns>
public IList GetListAllIList(object detail, IList objToFill)
{
IBaseSQLable sql = ReadSQL.GetSqlByDT(detail);
IDataReader dr = ExecuteForDataReader(sql.SQL_LIST_ALL);
return CBO.FillCollection(dr, detail.GetType(), objToFill);
}
/// <summary>
/// 根据SQL语句执行操作(无参数)。
/// </summary>
/// <param name="sql">SQL语句</param>
/// <returns>true 成功 false 失败</returns>
protected bool Execute(string sql)
{
return ExecuteForInt(sql) == 1 ? true : false;
}
/// <summary>
/// 根据SQL语句执行操作(含参数)。
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="parameters">参数数组</param>
/// <returns>true 成功 false 失败</returns>
protected bool Execute(string sql, IDataParameter[] parameters)
{
return ExecuteForInt(sql, parameters) == 1 ? true : false;
}
/// <summary>
/// 根据对象及操作类型执行操作。
/// </summary>
/// <param name="detail">一条记录</param>
/// <param name="operType">操作类型</param>
/// <returns>true 成功 false 失败</returns>
private bool Execute(object detail, OperType operType)
{
IBaseSQLable sql = GetBaseSQL(detail);
string sqlString = "";
IDataParameter[] parameters = null;
// 判断操作的类别
switch (operType)
{
// 添加
case OperType.ADD :
sqlString = sql.SQL_ADD;
parameters = sql.GetParameterADD(detail);
break;
// 修改
case OperType.EDIT :
sqlString = sql.SQL_EDIT;
parameters = sql.GetParameterEDIT(detail);
break;
// 删除
case OperType.DEL :
sqlString = sql.SQL_DEL;
parameters = sql.GetParameterDEL(detail);
break;
// 其它
default :
break;
}
return Execute(sqlString, parameters);
}
/// <summary>
/// 取得查询的到的行数。
/// </summary>
/// <param name="sql">SQL语句</param>
/// <returns>查询得到的行数</returns>
public int GetRows(string sql)
{
DataTable dt = ExecuteForDataTable(sql);
return dt.Rows.Count;
}
/// <summary>
/// 取得查询的到的行数。
/// </summary>
/// <param name="sql">SQL语句</param>
/// <param name="parameters">参数数组</param>
/// <returns>查询得到的行数</returns>
public int GetRows(string sql, IDataParameter[] parameters)
{
DataTable dt = ExecuteForDataTable(sql, parameters);
return dt.Rows.Count;
}
/// <summary>
/// 根据对象类型生成BaseSQL对象。
/// </summary>
/// <param name="detail">一个对象</param>
/// <returns>BaseSQL对象</returns>
private IBaseSQLable GetBaseSQL(object detail)
{
return ReadSQL.GetSqlByDT(detail);
}
/// <summary>
/// 根据对象类型取得DT对象。
/// </summary>
/// <param name="detail">一个对象</param>
/// <returns>一个DT对象</returns>
private BaseDT GetDT(object detail)
{
BaseDT baseDT = (BaseDT)Activator.CreateInstance("Data", detail.GetType().ToString()).Unwrap();
return baseDT;
}
}
/// <summary>
/// 操作类型。
/// </summary>
enum OperType
{
ADD = 1,
EDIT = 2,
GET = 4,
ALLLIST = 5
}
}
九、 总结
通过分析与改进,最后去掉了DB类,将增删改查都放入了DB基类中,增加了代码的重用性,减少了代码量。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步