如果想要很好的使用一件兵器,你必须了解它的秉性、它的优势劣势,掌握它的精神,从而扬长避短。使用XCodeFactory也是一样,要想它成为你的得力助手,你需要花一点时间来了解它。我可以向你保证,它一定不会让你失望的!
Hibernate/NHibernate虽然功能强大,但是使用困难度却比XCodeFactory大N倍。XCodeFactory使用简单,而且生成的数据层代码也很容易使用,但这并不就是说XCodeFactory的功能不够强,相反,对于绝大多数应用来说,XCodeFactory生成的代码足以满足我们的需要。XCodeFactory生成的数据层代码目前支持以下主要功能:
(1)支持三种数据访问接口。你对数据库表的所有操作基本上都包含于这三个接口中。
三种接口分别是查询接口(基于对象操作)、命令接口(添加/删除/修改,基于对象操作)、关系型接口(DataSet、DataReader ,基于关系操作)。另外还支持自动分页。
(2)支持SQL Server数据库和OLE数据库(如Access)。生成的数据库表访问类是两个(如StudentSqlDealer ,StudentOleDealer),一个用于Sql Server数据库,另一个用于Ole数据库。而数据库之间的相互切换只需要改变配置文件中的一个枚举的选择即可。
(3)支持自动增长的主键字段。
(4)支持Blob字段,并支持延迟加载Blob字段。也就是说你在从数据库取出一个对象时,可以先不取出其Blob字段(GetObjectsWithoutBlob方法),等到需要用到Blob字段时,在加载它(FillBlobData方法)。
(5)支持事物。命令接口中的所有方法都对事物提供支持。
(6)使用DataEntrance静态类,能进一步简化对自动生成的数据层的代码的使用。
数据层的主要功能就这么多,接下来说说XCodeFactory的设计思想。XCodeFactory的主要目标是使开发人员从SQL语句、从数据层解脱出来,也就是说,使用XCodeFactory之后,开发人员可以不用关心数据层的任何东西,而所要做的仅仅是维护cfp文件--XCodeFactory的项目文件,一个cfp文件对应数据库中的一个表。只要有cfp文件在手,我就可以使用XCodeFactory自动生成数据库中的表、对应的数据对象和对应的数据访问类。所以当需要修改某个数据库表的结构时,只需要XCodeFactory打开对应的cfp文件,修改其内容,点击生成按钮,然后重新编译你的VS项目。
你也许已经了解一些了,是的,思想是这样的,数据库中的一个表对应着一个cfp文件,也对应着一个数据对象,还对应着一个数据访问类(如果要区分数据库类型的话,目前对应的是两个访问类,一个针对SqlServer,另一个针对Ole数据库)。即
数据库表 《==》cfp文件 《==》数据对象类 《==》数据访问类(s)
所谓数据对象类,可以说是一个简单的数据结构,它的所有属性都与对应的数据库表中的字段一一对应,注意,是“一一对应”,而数据库类型也转换为对应的C#类型,如NVarChar转换为string、image转换为byte数组等等。
而一个对象(即一个数据对象类的实例)对应着数据库表中的一条记录。接下来举个例子。假设我们的系统中需要一个数据库表来保存教师Teacher的信息,表结构如下(该描述文件也是由XCodeFactory自动生成):

其中VideoInfo是对该教师的视频录像,是一个Blob。
对应的XCodeFactory的cfp项目操作界面如下:

点击生成按钮后,生成的数据对象类(即对应上图的“属性类文件”CheckBox)的代码如下:
public
class
Teacher

{
public Teacher()

{
}

ID#region ID
private string iD = "" ;

/**//// <summary>
/// 编号
/// </summary>
public string ID

{
get

{
return this.iD ;
}
set

{
this.iD = value ;
}
}
#endregion

Name#region Name
private string name = "" ;

/**//// <summary>
/// 姓名
/// </summary>
public string Name

{
get

{
return this.name ;
}
set

{
this.name = value ;
}
}
#endregion

Age#region Age
private int age = 0 ;

/**//// <summary>
/// 年龄
/// </summary>
public int Age

{
get

{
return this.age ;
}
set

{
this.age = value ;
}
}
#endregion

Description#region Description
private string description = "" ;

/**//// <summary>
/// 说明
/// </summary>
public string Description

{
get

{
return this.description ;
}
set

{
this.description = value ;
}
}
#endregion

VideoInfo#region VideoInfo
private byte[] videoInfo = null ;

/**//// <summary>
/// 视频资料
/// </summary>
public byte[] VideoInfo

{
get

{
return this.videoInfo ;
}
set

{
this.videoInfo = value ;
}
}
#endregion

ToString#region ToString
public override string ToString()

{
return this.ID.ToString() + " " + this.Name.ToString() ;
}
#endregion
}
生成的访问类TeacherSqlDealer ,TeacherOleDealer ,它们的代码就很复杂了,下面仅仅将访问类的接口列出:
/**/
/// <summary>
/// IDBAccesser 是最基本的数据服务对象--即数据库访问类 ,IDBAccesser提供了对ADO.NET事务的支持 。
/// 作者:朱伟 sky.zhuwei@163.com
/// </summary>
public
interface
IDBAccesser :IDBAccesserQuery ,IDBAccesserOrder ,IDBAccesserRelation

{
//property

string ConnectString
{get ;}

string DbTableName
{get ;}

DataBaseType DataBaseType
{get ;}

//others
IDataPaginationManager GetPaginationMgr(string selectStr ,string complexID_Name ,int page_size) ;
}


/**/
/// <summary>
/// IDBAccesserRelation 为执行sql关系型接口
/// </summary>
public
interface
IDBAccesserRelation

{
//RelationAction
int GetRecordsCount() ;
object ExecuteScalar(string command) ;
IDataReader GetReader(string select_str) ; //IDataReader用完后要及时关闭
}


/**/
/// <summary>
/// IDBAccesserQuery 为执行sql查询接口
/// </summary>
public
interface
IDBAccesserQuery

{
bool ReviseAObject(string where_str ,object target ) ;//使用数据库内容来更新当前对象
object GetAObject(string where_str) ;//if there is no condition clause ,please input ""
object[] GetObjects(string where_str) ;
object[] GetObjectsWithoutBlob(string where_str) ; //获取的对象中凡是Blob字段都未填充
bool FillBlobData(object obj) ; //填充某个对象的所有Blob字段
DataSet GetDataSet(string select_str) ;
}


/**/
/// <summary>
/// IDBAccesserOrder 为执行sql命令接口
/// </summary>
public
interface
IDBAccesserOrder

{
//如果不需要事务,trans以null传入
void Insert(object obj ,IDbTransaction trans) ;
void Update(object obj ,IDbTransaction trans) ;
void Delete(object ID ,IDbTransaction trans) ; //ID一般为int或string类型
void InsertBatch(ArrayList objs ,IDbTransaction trans) ;//批插入

//插入对象并返回自动编号标志
object InsertReturnIdentity(object obj ,IDbTransaction trans) ;
}
该接口与数据库类型无关,XCodeFactory自动生成的所有访问类都支持IDBAccesser接口。下面就让我们来看看如何的使用数据访问类:
//
IDBAccesser deal_Teacher = CommonInformation.DBFactory.CreateDBAccesser(typeof(Teacher)) ;
IDBAccesser deal_Teacher
=
new
TeacherSqlDealer(connStr) ;
//
取出所有年龄大于45岁的教师,并且暂时不需要视频资料(Blob)
Teacher[] teachers
=
(Teacher[])deal_Teacher.GetObjectsWithoutBlob(
"
Where Age > '45'
"
) ;
//
对teachers处理

//
当需要获得第五个教师的视频资料时
deal_Teacher.FillBlobData(teachers[
4
]) ;

//
播放视频
DisplayVideo(teachers[
4
].VideoInfo) ;

//
修改描述信息,更新数据库中该教师的信息
teachers[
4
].Description
=
"

"
;
deal_Teacher.Update(teachers[
4
]) ;
是不是很容易使用了。上面的代码只是使用自动生成的数据层代码的一种方式,使用DataEntrance,我们能更加简洁地完成上述任务。这个我们将会在后续的文章中提到。
已经晚了,就先写到这里吧。 如果对前面的讲述还有什么不明白的地方,请留言。也欢迎提出建议!