一般来说,对系统的分层,一般都需要下面几个层:实体层(Entity)、数据访问层(DAL)、业务逻辑层(BLL)、界面层(UI);而数据访问层,一般也会加入一个接口层(IDAL)。
在其中的实体层,一般是根据数据库进行映射外加入注释等,技术含量不大,在此一笔带过;数据库访问层和业务逻辑层,是关键之所在,因为这里好的设计,会利用很多基类的操作,减少很多代码和重复劳动;界面层,不管是WebForm还是WinForm,都是尽可能少的逻辑代码或者SQL语句在其中,好的项目可能会利用一些优秀的控件进去,提高体验,减少代码。另外,由于一些创建操作费时费资源,一般还需要把可重复利用的资源缓存起来,提高性能。
先给大家预览下项目的框架,再一层层分析讨论:
1、 实体层(定义一个空的基类,其他实体类继承之,主要是为了利用泛型操作,用途下面细说)
public
class
BaseEntity
{
}
public
class
EquipmentInfo : BaseEntity
{
Field Members
#region
Field Members
private
int
m_ID
=
0
;
//
ID
private
string
m_PartID
=
""
;
//
备件编号
//
#endregion
Property Members
#region
Property Members
/**/
///
<summary>
///
ID
///
</summary>
public
virtual
int
ID
{
get
{
return
this
.m_ID;
}
set
{
this
.m_ID
=
value;
}
}
/**/
///
<summary>
///
备件编号
///
</summary>
public
virtual
string
PartID
{
get
{
return
this
.m_PartID;
}
set
{
this
.m_PartID
=
value;
}
}
//
#endregion
} 2、 数据库访问层,数据访问层的关键是数据访问基类的设计,基类实现大多数数据库的日常操作,如下:
/**/
///
<summary>
///
数据访问层的基类
///
</summary>
public
abstract
class
BaseDAL
<
T
>
: IBaseDAL
<
T
>
where
T : BaseEntity,
new
()
{
} BaseEntity就是实体类的基类,IBaseDAL是定义的数据访问基类接口,包含各种常用的操作定义;因此BaseDAL就是要对各种操作的进行实现,实现接口越多,将来继承类的重用程度就越高。
以上通过泛型
<
T
>
,我们就可以知道实例化那个具体访问类的信息了,可以实现强类型的函数定义。
/**/
///
<summary>
///
一些基本的,作为辅助函数的接口
///
</summary>
public
interface
IBaseDAL
<
T
>
where
T : BaseEntity
{
/**/
///
<summary>
///
查询数据库,检查是否存在指定键值的对象
///
</summary>
///
<param name="recordTable">
Hashtable:键[key]为字段名;值[value]为字段对应的值
</param>
///
<returns>
存在则返回
<c>
true
</c>
,否则为
<c>
false
</c>
。
</returns>
bool
IsExistKey(Hashtable recordTable);
/**/
///
<summary>
///
查询数据库,检查是否存在指定键值的对象
///
</summary>
///
<param name="fieldName">
指定的属性名
</param>
///
<param name="key">
指定的值
</param>
///
<returns>
存在则返回
<c>
true
</c>
,否则为
<c>
false
</c>
。
</returns>
bool
IsExistKey(
string
fieldName,
object
key);
/**/
///
<summary>
///
获取数据库中该对象的最大ID值
///
</summary>
///
<returns>
最大ID值
</returns>
int
GetMaxID();
/**/
///
<summary>
///
根据指定对象的ID,从数据库中删除指定对象
///
</summary>
///
<param name="key">
指定对象的ID
</param>
///
<returns>
执行成功返回
<c>
true
</c>
,否则为
<c>
false
</c>
。
</returns>
bool
DeleteByKey(
string
key);
/**/
///
<summary>
///
根据条件,从数据库中删除指定对象
///
</summary>
///
<param name="condition">
删除记录的条件语句
</param>
///
<returns>
执行成功返回
<c>
true
</c>
,否则为
<c>
false
</c>
。
</returns>
bool
DeleteByCondition(
string
condition);
/**/
///
<summary>
///
插入指定对象到数据库中
///
</summary>
///
<param name="obj">
指定的对象
</param>
///
<returns>
执行成功返回True
</returns>
bool
Insert(T obj);
/**/
///
<summary>
///
更新对象属性到数据库中
///
</summary>
///
<param name="obj">
指定的对象
</param>
///
<returns>
执行成功返回
<c>
true
</c>
,否则为
<c>
false
</c>
。
</returns>
bool
Update(T obj,
string
primaryKeyValue);
/**/
///
<summary>
///
查询数据库,检查是否存在指定ID的对象(用于整型主键)
///
</summary>
///
<param name="key">
对象的ID值
</param>
///
<returns>
存在则返回指定的对象,否则返回Null
</returns>
T FindByID(
int
key);
/**/
///
<summary>
///
查询数据库,检查是否存在指定ID的对象(用于字符型主键)
///
</summary>
///
<param name="key">
对象的ID值
</param>
///
<returns>
存在则返回指定的对象,否则返回Null
</returns>
T FindByID(
string
key);
返回集合的接口
#region
返回集合的接口
/**/
///
<summary>
///
根据ID字符串(逗号分隔)获取对象列表
///
</summary>
///
<param name="idString">
ID字符串(逗号分隔)
</param>
///
<returns>
符合条件的对象列表
</returns>
List
<
T
>
FindByIDs(
string
idString);
/**/
///
<summary>
///
根据条件查询数据库,并返回对象集合
///
</summary>
///
<param name="condition">
查询的条件
</param>
///
<returns>
指定对象的集合
</returns>
List
<
T
>
Find(
string
condition);
/**/
///
<summary>
///
根据条件查询数据库,并返回对象集合(用于分页数据显示)
///
</summary>
///
<param name="condition">
查询的条件
</param>
///
<param name="info">
分页实体
</param>
///
<returns>
指定对象的集合
</returns>
List
<
T
>
Find(
string
condition, PagerInfo info);
/**/
///
<summary>
///
返回数据库所有的对象集合
///
</summary>
///
<returns>
指定对象的集合
</returns>
List
<
T
>
GetAll();
/**/
///
<summary>
///
返回数据库所有的对象集合(用于分页数据显示)
///
</summary>
///
<param name="info">
分页实体信息
</param>
///
<returns>
指定对象的集合
</returns>
List
<
T
>
GetAll(PagerInfo info);
DataSet GetAllToDataSet(PagerInfo info);
#endregion
} 细看上面代码,会发现由一个PagerInfo 的类,这个类是用来做分页参数传递作用的,根据这个参数,你可以知道具体返回那些关心的记录信息,这些记录又转换为强类型的List
<
T
>
集合。
再看看数据库访问基类的具体实现代码吧:
/**/
///
<summary>
///
数据访问层的基类
///
</summary>
public
abstract
class
BaseDAL
<
T
>
: IBaseDAL
<
T
>
where
T : BaseEntity,
new
()
{
构造函数
#region
构造函数
protected
string
tableName;
//
需要初始化的对象表名
protected
string
primaryKey;
//
数据库的主键字段名
protected
string
sortField
=
"
LastUpdated
"
;
//
排序字段
private
bool
isDescending
=
true
;
//
/**/
///
<summary>
///
排序字段
///
</summary>
public
string
SortField
{
get
{
return
sortField;
}
set
{
sortField
=
value;
}
}
/**/
///
<summary>
///
是否为降序
///
</summary>
public
bool
IsDescending
{
get
{
return
isDescending; }
set
{ isDescending
=
value; }
}
/**/
///
<summary>
///
数据库访问对象的表名
///
</summary>
public
string
TableName
{
get
{
return
tableName;
}
}
/**/
///
<summary>
///
数据库访问对象的外键约束
///
</summary>
public
string
PrimaryKey
{
get
{
return
primaryKey;
}
}
public
BaseDAL()
{}
/**/
///
<summary>
///
指定表名以及主键,对基类进构造
///
</summary>
///
<param name="tableName">
表名
</param>
///
<param name="primaryKey">
表主键
</param>
public
BaseDAL(
string
tableName,
string
primaryKey)
{
this
.tableName
=
tableName;
this
.primaryKey
=
primaryKey;
}
#endregion
通用操作方法
#region
通用操作方法
/**/
///
<summary>
///
添加记录
///
</summary>
///
<param name="recordField">
Hashtable:键[key]为字段名;值[value]为字段对应的值
</param>
///
<param name="trans">
事务对象,如果使用事务,传入事务对象,否则为Null不使用事务
</param>
public
bool
Insert(Hashtable recordField, DbTransaction trans)
{
return
this
.Insert(recordField, tableName, trans);
}
/**/
///
<summary>
///
添加记录
///
</summary>
///
<param name="recordField">
Hashtable:键[key]为字段名;值[value]为字段对应的值
</param>
///
<param name="targetTable">
需要操作的目标表名称
</param>
///
<param name="trans">
事务对象,如果使用事务,传入事务对象,否则为Null不使用事务
</param>
public
bool
Insert(Hashtable recordField,
string
targetTable, DbTransaction trans)
{
bool
result
=
false
;
string
fields
=
""
;
//
字段名
string
vals
=
""
;
//
字段值
if
( recordField
==
null
||
recordField.Count
<
1
)
{
return
result;
}
SqlParameter[] param
=
new
SqlParameter[recordField.Count];
IEnumerator eKeys
=
recordField.Keys.GetEnumerator();
int
i
=
0
;
while
( eKeys.MoveNext() )
{
string
field
=
eKeys.Current.ToString();
fields
+=
field
+
"
,
"
;
vals
+=
string
.Format(
"
@{0},
"
, field);
object
val
=
recordField[eKeys.Current.ToString()];
param[i]
=
new
SqlParameter(
"
@
"
+
field, val);
i
++
;
}
fields
=
fields.Trim(
'
,
'
);
//
除去前后的逗号
vals
=
vals.Trim(
'
,
'
);
//
除去前后的逗号
string
sql
=
string
.Format(
"
INSERT INTO {0} ({1}) VALUES ({2})
"
, targetTable, fields, vals);
Database db
=
DatabaseFactory.CreateDatabase();
DbCommand command
=
db.GetSqlStringCommand(sql);
command.Parameters.AddRange(param);
if
( trans
!=
null
)
{
result
=
db.ExecuteNonQuery(command, trans)
>
0
;
}
else
{
result
=
db.ExecuteNonQuery(command)
>
0
;
}
return
result;
}
/**/
///
<summary>
///
更新某个表一条记录(只适用于用单键,用int类型作键值的表)
///
</summary>
///
<param name="id">
ID号
</param>
///
<param name="recordField">
Hashtable:键[key]为字段名;值[value]为字段对应的值
</param>
///
<param name="trans">
事务对象,如果使用事务,传入事务对象,否则为Null不使用事务
</param>
public
bool
Update(
int
id, Hashtable recordField, DbTransaction trans)
{
return
this
.Update(id, recordField, tableName, trans);
}
/**/
///
<summary>
///
更新某个表一条记录(只适用于用单键,用string类型作键值的表)
///
</summary>
///
<param name="id">
ID号
</param>
///
<param name="recordField">
Hashtable:键[key]为字段名;值[value]为字段对应的值
</param>
///
<param name="trans">
事务对象,如果使用事务,传入事务对象,否则为Null不使用事务
</param>
public
bool
Update(
string
id, Hashtable recordField, DbTransaction trans)
{
return
this
.Update(id, recordField, tableName, trans);
}
/**/
///
<summary>
///
更新某个表一条记录(只适用于用单键,用int类型作键值的表)
///
</summary>
///
<param name="id">
ID号
</param>
///
<param name="recordField">
Hashtable:键[key]为字段名;值[value]为字段对应的值
</param>
///
<param name="targetTable">
需要操作的目标表名称
</param>
///
<param name="trans">
事务对象,如果使用事务,传入事务对象,否则为Null不使用事务
</param>
public
bool
Update(
int
id, Hashtable recordField,
string
targetTable, DbTransaction trans)
{
return
Update(id, recordField, targetTable, trans);
}
/**/
///
<summary>
///
更新某个表一条记录(只适用于用单键,用string类型作键值的表)
///
</summary>
///
<param name="id">
ID号
</param>
///
<param name="recordField">
Hashtable:键[key]为字段名;值[value]为字段对应的值
</param>
///
<param name="targetTable">
需要操作的目标表名称
</param>
///
<param name="trans">
事务对象,如果使用事务,传入事务对象,否则为Null不使用事务
</param>
public
bool
Update(
string
id, Hashtable recordField,
string
targetTable, DbTransaction trans)
{
string
field
=
""
;
//
字段名
object
val
=
null
;
//
值
string
setValue
=
""
;
//
更新Set () 中的语句
if
( recordField
==
null
||
recordField.Count
<
1
)
{
return
false
;
}
SqlParameter[] param
=
new
SqlParameter[recordField.Count];
int
i
=
0
;
IEnumerator eKeys
=
recordField.Keys.GetEnumerator();
while
( eKeys.MoveNext() )
{
field
=
eKeys.Current.ToString();
val
=
recordField[eKeys.Current.ToString()];
setValue
+=
string
.Format(
"
{0} = @{0},
"
, field);
param[i]
=
new
SqlParameter(
string
.Format(
"
@{0}
"
, field), val);
i
++
;
}
string
sql
=
string
.Format(
"
UPDATE {0} SET {1} WHERE {2} = '{3}'
"
, targetTable, setValue.Substring(
0
, setValue.Length
-
1
), primaryKey, id);
Database db
=
DatabaseFactory.CreateDatabase();
DbCommand command
=
db.GetSqlStringCommand(sql);
command.Parameters.AddRange(param);
bool
result
=
false
;
if
(trans
!=
null
)
{
result
=
db.ExecuteNonQuery(command, trans)
>
0
;
}
else
{
result
=
db.ExecuteNonQuery(command)
>
0
;
}
return
result;
}
#endregion
对象添加、修改、查询接口
#region
对象添加、修改、查询接口
/**/
///
<summary>
///
插入指定对象到数据库中
///
</summary>
///
<param name="obj">
指定的对象
</param>
///
<returns>
执行成功返回新增记录的自增长ID。
</returns>
public
bool
Insert(T obj)
{
ArgumentValidation.CheckForNullReference(obj,
"
传入的对象obj为空
"
);
Hashtable hash
=
GetHashByEntity(obj);
return
Insert(hash,
null
);
}
/**/
///
<summary>
///
更新对象属性到数据库中
///
</summary>
///
<param name="obj">
指定的对象
</param>
///
<returns>
执行成功返回
<c>
true
</c>
,否则为
<c>
false
</c>
。
</returns>
public
bool
Update(T obj,
string
primaryKeyValue)
{
ArgumentValidation.CheckForNullReference(obj,
"
传入的对象obj为空
"
);
Hashtable hash
=
GetHashByEntity(obj);
return
Update(primaryKeyValue, hash,
null
);
}
/**/
///
<summary>
///
查询数据库,检查是否存在指定ID的对象(用于整型主键)
///
</summary>
///
<param name="key">
对象的ID值
</param>
///
<returns>
存在则返回指定的对象,否则返回Null
</returns>
public
T FindByID(
int
key)
{
return
FindByID(key.ToString());
}
/**/
///
<summary>
///
查询数据库,检查是否存在指定ID的对象(用于字符型主键)
///
</summary>
///
<param name="key">
对象的ID值
</param>
///
<returns>
存在则返回指定的对象,否则返回Null
</returns>
public
T FindByID(
string
key)
{
string
sql
=
string
.Format(
"
Select * From dbo.{0} Where ({1} = @ID)
"
, tableName, primaryKey);
SqlParameter param
=
new
SqlParameter(
"
@ID
"
, key);
Database db
=
DatabaseFactory.CreateDatabase();
DbCommand command
=
db.GetSqlStringCommand(sql);
command.Parameters.Add(param);
T entity
=
null
;
using
(IDataReader dr
=
db.ExecuteReader(command))
{
if
(dr.Read())
{
entity
=
DataReaderToEntity(dr);
}
}
return
entity;
}
#endregion
返回集合的接口
#region
返回集合的接口
/**/
///
<summary>
///
根据ID字符串(逗号分隔)获取对象列表
///
</summary>
///
<param name="idString">
ID字符串(逗号分隔)
</param>
///
<returns>
符合条件的对象列表
</returns>
public
List
<
T
>
FindByIDs(
string
idString)
{
string
condition
=
string
.Format(
"
{0} in({1})
"
, primaryKey, idString);
return
this
.Find(condition);
}
/**/
///
<summary>
///
根据条件查询数据库,并返回对象集合
///
</summary>
///
<param name="condition">
查询的条件
</param>
///
<returns>
指定对象的集合
</returns>
public
List
<
T
>
Find(
string
condition)
{
//
串连条件语句为一个完整的Sql语句
string
sql
=
string
.Format(
"
Select * From dbo.{0} Where
"
, tableName);
sql
+=
condition;
sql
+=
string
.Format(
"
Order by {0} {1}
"
, sortField, isDescending
?
"
DESC
"
:
"
ASC
"
);
T entity
=
null
;
List
<
T
>
list
=
new
List
<
T
>
();
Database db
=
DatabaseFactory.CreateDatabase();
DbCommand command
=
db.GetSqlStringCommand(sql);
using
(IDataReader dr
=
db.ExecuteReader(command))
{
while
(dr.Read())
{
entity
=
DataReaderToEntity(dr);
list.Add(entity);
}
}
return
list;
}
/**/
///
<summary>
///
根据条件查询数据库,并返回对象集合(用于分页数据显示)
///
</summary>
///
<param name="condition">
查询的条件
</param>
///
<param name="info">
分页实体
</param>
///
<returns>
指定对象的集合
</returns>
public
List
<
T
>
Find(
string
condition, PagerInfo info)
{
List
<
T
>
list
=
new
List
<
T
>
();
Database db
=
DatabaseFactory.CreateDatabase();
PagerHelper helper
=
new
PagerHelper(tableName, condition);
info.RecordCount
=
helper.GetCount();
PagerHelper helper2
=
new
PagerHelper(tableName,
false
,
"
*
"
, sortField,
info.PageSize, info.CurrenetPageIndex,
true
, condition);
using
(IDataReader dr
=
helper2.GetDataReader())
{
while
(dr.Read())
{
list.Add(
this
.DataReaderToEntity(dr));
}
}
return
list;
}
/**/
///
<summary>
///
返回数据库所有的对象集合
///
</summary>
///
<returns>
指定对象的集合
</returns>
public
List
<
T
>
GetAll()
{
string
sql
=
string
.Format(
"
Select * From dbo.{0}
"
, tableName);
sql
+=
string
.Format(
"
Order by {0} {1}
"
, sortField, isDescending
?
"
DESC
"
:
"
ASC
"
);
T entity
=
null
;
List
<
T
>
list
=
new
List
<
T
>
();
Database db
=
DatabaseFactory.CreateDatabase();
DbCommand command
=
db.GetSqlStringCommand(sql);
using
(IDataReader dr
=
db.ExecuteReader(command))
{
while
(dr.Read())
{
entity
=
DataReaderToEntity(dr);
list.Add(entity);
}
}
return
list;
}
/**/
///
<summary>
///
返回数据库所有的对象集合(用于分页数据显示)
///
</summary>
///
<param name="info">
分页实体信息
</param>
///
<returns>
指定对象的集合
</returns>
public
List
<
T
>
GetAll(PagerInfo info)
{
List
<
T
>
list
=
new
List
<
T
>
();
string
condition
=
""
;
Database db
=
DatabaseFactory.CreateDatabase();
PagerHelper helper
=
new
PagerHelper(tableName, condition);
info.RecordCount
=
helper.GetCount();
PagerHelper helper2
=
new
PagerHelper(tableName,
false
,
"
*
"
, sortField,
info.PageSize, info.CurrenetPageIndex,
true
, condition);
using
(IDataReader dr
=
helper2.GetDataReader())
{
while
(dr.Read())
{
list.Add(
this
.DataReaderToEntity(dr));
}
}
return
list;
}
public
DataSet GetAllToDataSet(PagerInfo info)
{
DataSet ds
=
new
DataSet();
string
condition
=
""
;
PagerHelper helper
=
new
PagerHelper(tableName, condition);
info.RecordCount
=
helper.GetCount();
PagerHelper helper2
=
new
PagerHelper(tableName,
false
,
"
*
"
, sortField,
info.PageSize, info.CurrenetPageIndex,
true
, condition);
return
helper2.GetDataSet();
}
#endregion
子类必须实现的函数(用于更新或者插入)
#region
子类必须实现的函数(用于更新或者插入)
/**/
///
<summary>
///
将DataReader的属性值转化为实体类的属性值,返回实体类
///
(提供了默认的反射机制获取信息,为了提高性能,建议重写该函数)
///
</summary>
///
<param name="dr">
有效的DataReader对象
</param>
///
<returns>
实体类对象
</returns>
protected
virtual
T DataReaderToEntity(IDataReader dr)
{
T obj
=
new
T();
PropertyInfo[] pis
=
obj.GetType().GetProperties();
foreach
(PropertyInfo pi
in
pis)
{
try
{
if
(dr[pi.Name].ToString()
!=
""
)
{
pi.SetValue(obj, dr[pi.Name]
??
""
,
null
);
}
}
catch
{ }
}
return
obj;
}
/**/
///
<summary>
///
将实体对象的属性值转化为Hashtable对应的键值(用于插入或者更新操作)
///
(提供了默认的反射机制获取信息,为了提高性能,建议重写该函数)
///
</summary>
///
<param name="obj">
有效的实体对象
</param>
///
<returns>
包含键值映射的Hashtable
</returns>
protected
virtual
Hashtable GetHashByEntity(T obj)
{
Hashtable ht
=
new
Hashtable();
PropertyInfo[] pis
=
obj.GetType().GetProperties();
for
(
int
i
=
0
; i
<
pis.Length; i
++
)
{
//
if (pis[i].Name != PrimaryKey)
{
object
objValue
=
pis[i].GetValue(obj,
null
);
objValue
=
(objValue
==
null
)
?
DBNull.Value : objValue;
if
(
!
ht.ContainsKey(pis[i].Name))
{
ht.Add(pis[i].Name, objValue);
}
}
}
return
ht;
}
#endregion
IBaseDAL接口
#region
IBaseDAL接口
/**/
///
<summary>
///
查询数据库,检查是否存在指定键值的对象
///
</summary>
///
<param name="recordTable">
Hashtable:键[key]为字段名;值[value]为字段对应的值
</param>
///
<returns>
存在则返回
<c>
true
</c>
,否则为
<c>
false
</c>
。
</returns>
public
bool
IsExistKey(Hashtable recordTable)
{
SqlParameter[] param
=
new
SqlParameter[recordTable.Count];
IEnumerator eKeys
=
recordTable.Keys.GetEnumerator();
string
fields
=
""
;
//
字段名
int
i
=
0
;
while
(eKeys.MoveNext())
{
string
field
=
eKeys.Current.ToString();
fields
+=
string
.Format(
"
{0} = @{1} AND
"
, field, field);
string
val
=
recordTable[eKeys.Current.ToString()].ToString();
param[i]
=
new
SqlParameter(
string
.Format(
"
@{0}
"
,field), val);
i
++
;
}
fields
=
fields.Substring(
0
, fields.Length
-
3
);
//
除去最后的AND
string
sql
=
string
.Format(
"
SELECT COUNT(*) FROM {0} WHERE {1}
"
, tableName, fields);
Database db
=
DatabaseFactory.CreateDatabase();
DbCommand command
=
db.GetSqlStringCommand(sql);
command.Parameters.AddRange(param);
return
(
int
)db.ExecuteScalar(command)
>
0
;
}
/**/
///
<summary>
///
查询数据库,检查是否存在指定键值的对象
///
</summary>
///
<param name="fieldName">
指定的属性名
</param>
///
<param name="key">
指定的值
</param>
///
<returns>
存在则返回
<c>
true
</c>
,否则为
<c>
false
</c>
。
</returns>
public
bool
IsExistKey(
string
fieldName,
object
key)
{
Hashtable table
=
new
Hashtable();
table.Add(fieldName, key);
return
IsExistKey(table);
}
/**/
///
<summary>
///
获取数据库中该对象的最大ID值
///
</summary>
///
<returns>
最大ID值
</returns>
public
int
GetMaxID()
{
string
sql
=
string
.Format(
"
SELECT MAX({0}) AS MaxID FROM dbo.{1}
"
, primaryKey, tableName);
Database db
=
DatabaseFactory.CreateDatabase();
DbCommand command
=
db.GetSqlStringCommand(sql);
object
obj
=
db.ExecuteScalar(command);
if
(Convert.IsDBNull(obj))
{
return
0
;
//
没有记录的时候为0
}
return
Convert.ToInt32(obj);
}
/**/
///
<summary>
///
根据指定对象的ID,从数据库中删除指定对象(用于整型主键)
///
</summary>
///
<param name="key">
指定对象的ID
</param>
///
<returns>
执行成功返回
<c>
true
</c>
,否则为
<c>
false
</c>
。
</returns>
public
bool
DeleteByKey(
string
key)
{
string
condition
=
string
.Format(
"
{0} = '{1}'
"
, primaryKey, key);
return
DeleteByCondition(condition);
}
/**/
///
<summary>
///
根据指定条件,从数据库中删除指定对象
///
</summary>
///
<param name="condition">
删除记录的条件语句
</param>
///
<returns>
执行成功返回
<c>
true
</c>
,否则为
<c>
false
</c>
。
</returns>
public
bool
DeleteByCondition(
string
condition)
{
string
sql
=
string
.Format(
"
DELETE FROM dbo.{0} WHERE {1}
"
, tableName, condition);
Database db
=
DatabaseFactory.CreateDatabase();
DbCommand command
=
db.GetSqlStringCommand(sql);
return
db.ExecuteNonQuery(command)
>
0
;
}
#endregion
}
3、具体的数据访问类
基类完成所有的操作了,对于具体的类将是一大福音,说明它的工作减少很多了,下面看看具体的实现过程。定义一个数据访问类接口,然后实现接口和继承基类即可。
public
interface
IEquipment : IBaseDAL
<
EquipmentInfo
>
{
}
public
class
Equipment : BaseDAL
<
EquipmentInfo
>
, IEquipment
{
对象实例及构造函数
#region
对象实例及构造函数
public
static
Equipment Instance
{
get
{
return
new
Equipment();
}
}
public
Equipment() :
base
(
"
Equipment
"
,
"
ID
"
)
{
}
#endregion
} 其实这样就完成了,我们为了提高效率,重载两个函数的实现,避免基类的属性反射带来的性能损失,这两个函数看似很复杂,其实通过代码生成工具,生成起来也是毫不费功夫的。。
protected
override
EquipmentInfo DataReaderToEntity(IDataReader dataReader)
protected
override
Hashtable GetHashByEntity(EquipmentInfo obj) 因此最后的代码就变为下面
public
class
Equipment : BaseDAL
<
EquipmentInfo
>
, IEquipment
{
对象实例及构造函数
#region
对象实例及构造函数
public
static
Equipment Instance
{
get
{
return
new
Equipment();
}
}
public
Equipment() :
base
(
"
Equipment
"
,
"
ID
"
)
{
}
#endregion
/**/
///
<summary>
///
将DataReader的属性值转化为实体类的属性值,返回实体类
///
</summary>
///
<param name="dr">
有效的DataReader对象
</param>
///
<returns>
实体类对象
</returns>
protected
override
EquipmentInfo DataReaderToEntity(IDataReader dataReader)
{
EquipmentInfo equipmentInfo
=
new
EquipmentInfo();
SmartDataReader reader
=
new
SmartDataReader(dataReader);
equipmentInfo.ID
=
reader.GetInt32(
"
ID
"
);
equipmentInfo.PartID
=
reader.GetString(
"
PartID
"
);
equipmentInfo.Name
=
reader.GetString(
"
Name
"
);
equipmentInfo.EquipmentType
=
reader.GetString(
"
EquipmentType
"
);
equipmentInfo.Specification
=
reader.GetString(
"
Specification
"
);
equipmentInfo.Manufacturer
=
reader.GetString(
"
Manufacturer
"
);
equipmentInfo.Picture
=
reader.GetBytes(
"
Picture
"
);
equipmentInfo.ApplyEquipment
=
reader.GetString(
"
ApplyEquipment
"
);
equipmentInfo.BuyAmount
=
reader.GetInt32(
"
BuyAmount
"
);
equipmentInfo.BuyDate
=
reader.GetDateTime(
"
BuyDate
"
);
equipmentInfo.Status
=
reader.GetString(
"
Status
"
);
equipmentInfo.UserName
=
reader.GetString(
"
UserName
"
);
equipmentInfo.SafeNumber
=
reader.GetInt32(
"
SafeNumber
"
);
equipmentInfo.Note
=
reader.GetString(
"
Note
"
);
return
equipmentInfo;
}
/**/
///
<summary>
///
将实体对象的属性值转化为Hashtable对应的键值
///
</summary>
///
<param name="obj">
有效的实体对象
</param>
///
<returns>
包含键值映射的Hashtable
</returns>
protected
override
Hashtable GetHashByEntity(EquipmentInfo obj)
{
EquipmentInfo info
=
obj
as
EquipmentInfo;
Hashtable hash
=
new
Hashtable();
hash.Add(
"
ID
"
, info.ID);
hash.Add(
"
PartID
"
, info.PartID);
hash.Add(
"
Name
"
, info.Name);
hash.Add(
"
EquipmentType
"
, info.EquipmentType);
hash.Add(
"
Specification
"
, info.Specification);
hash.Add(
"
Manufacturer
"
, info.Manufacturer);
hash.Add(
"
Picture
"
, info.Picture);
hash.Add(
"
ApplyEquipment
"
, info.ApplyEquipment);
hash.Add(
"
BuyAmount
"
, info.BuyAmount);
hash.Add(
"
BuyDate
"
, info.BuyDate);
hash.Add(
"
Status
"
, info.Status);
hash.Add(
"
UserName
"
, info.UserName);
hash.Add(
"
SafeNumber
"
, info.SafeNumber);
hash.Add(
"
Note
"
, info.Note);
return
hash;
}
}
文章太长,下面关于逻辑层、缓存、界面部分的设计在下一篇文章中介绍。
以上所引用的代码是通过代码生成工具Database2Sharp自动生成(
http://www.iqidi.com/Database2Sharp.htm
),选择EnterpriseLibrary架构即可。