一般来说,对系统的分层,一般都需要下面几个层:实体层(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架构即可。
