您的位置:首页 > 编程语言

微型项目实践(2):用测试驱动代码生成

2008-05-03 16:20 411 查看
上一篇文章中,我们分析了系统的两个实体类,并且给出了对应的实体XML。今天我们来看看如何根据这个XML进行代码生成。

1:<?xmlversion="1.0"encoding="utf-8"?>
2:<Entitiesxmlns="http://it.ouc.edu.cn/EntityDescription/V2">
3:<Entitytitle="日志"name="Blog"module="Blogs">
4:<Itemtitle="标题"name="Title"type="text"require="true"/>
5:<Itemtitle="内容"name="Content"type="longtext"require="false"/>
6:<Itemtitle="所属分类"name="BlogClass"type="entity"entityName="BlogClass"require="false"/>
7:<Itemtitle="创建时间"name="CreateDateTime"type="datetime"require="true"/>
8:<Itemtitle="更新时间"name="UpdateDateTime"type="datetime"require="true"/>
9:</Entity>
10:<Entitytitle="日志分类"name="BlogClass"module="Blogs">
11:<Itemtitle="名称"name="Name"type="text"require="true"/>
12:<Itemtitle="描述"name="Description"type="text"require="false"/>
13:</Entity>
14:</Entities>

这里我们主要是生成两种最重要的代码,一是数据库的建库脚本,二是实体的CS类。
我们使用测试来驱动代码生成,在项目DongBlog.Test中添加一个新的单元测试:Util.cs。对应的代码如下:

1:using...
12:
13:namespaceDongBlog.Test
14:{
15:///<summary>
16:///数据库相关的工具方法
17:///</summary>
18:[TestClass]
19:publicclassDatabaseUtil
20:{
21:///<summary>
22:///构造建库脚本
23:///</summary>
24:[TestMethod,Description("构造建库脚本")]
25:publicvoidUtil_CreateDatabaseScript()
26:{
27:varentities=getEntities();
28:stringsqlText=MsSqlServerScriptBuilder.getSqlScript(entities);
29:
30:Debug.WriteLine("");
31:Debug.WriteLine("Thefollowingisthedatabasecreatingscript:");
32:Debug.WriteLine("=============================彪悍的分割线==============================================================================");
33:Debug.WriteLine("");
34:Debug.WriteLine("");
35:Debug.WriteLine(sqlText);
36:Debug.WriteLine("");
37:Debug.WriteLine("");
38:Debug.WriteLine("=============================又见彪悍的分割线==========================================================================");
39:}
40:
41:privateEntity[]getEntities()
42:{
43:XmlDocumentdocument=newXmlDocument();
44:document.Load(Gobal.EntityXmlFileName);
45:returnEntityXmlParser.ParseXml(document);
46:}
47:}
48:}

这个类中定义的个单元测试,并不测试任何功能代码,而是用于生成数据库的建库脚本。VS.Net中似乎没有Make这样的自动化脚本,使用第三方的组件和工具则略显繁琐,而这种单元测试的“歪用”能起到不错的效果。:)

单元测试充当自动化脚本还可以实现很多功能,常用的除了上面的生成数据库脚本外,还有生成实体类代码、生成Linq的外置XML映射文件、填充测试数据、从旧版本系统中导入数据、统计代码行数等,大家可以尽情的发挥想象,呵呵。

回到我们的系统中,使用Debug的方式运行Util_CreateDatabaseScript测试,数据库脚本会写入到Output窗口中(使用快捷键Ctrl+W、O打开)。

1:ifexists(select*fromdbo.sysobjectswhereid=object_id(N'[dbo].[FK_Blog_BlogClass]')andOBJECTPROPERTY(id,N'IsForeignKey')=1)
2:ALTERTABLE[dbo].[Blog]DROPCONSTRAINTFK_Blog_BlogClass
3:GO
4:
5:ifexists(select*fromdbo.sysobjectswhereid=object_id(N'[dbo].[Blog]')andOBJECTPROPERTY(id,N'IsUserTable')=1)
6:droptable[dbo].[Blog]
7:GO
8:
9:ifexists(select*fromdbo.sysobjectswhereid=object_id(N'[dbo].[BlogClass]')andOBJECTPROPERTY(id,N'IsUserTable')=1)
10:droptable[dbo].[BlogClass]
11:GO
12:
13:CREATETABLE[dbo].[Blog](
14:[ID][int]IDENTITY(1,1)NOTNULL,
15:[Title][nvarchar](255)COLLATEChinese_PRC_CI_ASNOTNULL,
16:[Content][text]COLLATEChinese_PRC_CI_AS,
17:[BlogClassID][int],
18:[CreateDateTime][datetime]NOTNULL,
19:[UpdateDateTime][datetime]NOTNULL,
20:[TimeStamp][timestamp]NULL
21:)ON[PRIMARY]
22:GO
23:
24:CREATETABLE[dbo].[BlogClass](
25:[ID][int]IDENTITY(1,1)NOTNULL,
26:[Name][nvarchar](255)COLLATEChinese_PRC_CI_ASNOTNULL,
27:[Description][nvarchar](255)COLLATEChinese_PRC_CI_AS,
28:[TimeStamp][timestamp]NULL
29:)ON[PRIMARY]
30:GO
31:
32:ALTERTABLE[dbo].[Blog]WITHNOCHECKADD
33:CONSTRAINT[PK_Blog]PRIMARYKEYCLUSTERED
34:(
35:[ID]
36:)ON[PRIMARY]
37:GO
38:ALTERTABLE[dbo].[BlogClass]WITHNOCHECKADD
39:CONSTRAINT[PK_BlogClass]PRIMARYKEYCLUSTERED
40:(
41:[ID]
42:)ON[PRIMARY]
43:GO
44:ALTERTABLE[dbo].[Blog]WITHNOCHECKADD
45:CONSTRAINT[FK_Blog_BlogClass]FOREIGNKEY
46:(
47:[BlogClassID]
48:)REFERENCES[dbo].[BlogClass](
49:[ID]
50:)
51:GO

这里数据库脚本的生成借鉴了ROR的一些优点,比如为每个实体添加ID主键和时间戳。另外,实体数据字段类型对应到了具体的数据库类型(bool->bit,text->nvarchar(255)等),而实体间关系对应到表间关系。至于具体的对应规则和生成方式,可以根据项目和所采用数据库的不同进行调整。

自动化的优点就在于,每次我们修改实体XML后,只要重新生成一遍数据库脚本,就可以完成数据库的更新,这点在团队开发中很有用,任何人修改数据库都只需要通知同伴更新一下即可。而在项目每一轮迭代完成、进行发布的时候,也可以方便的获取数据库脚本。

生成器的代码在YD.Data.EntityPrase和YD.Data.DatabaseScriptGenerater这两个命名空间下。很简单,无非是拼字符串而已,大家可以参考一下,根据自己的需要编写自己的生成器(我一直认为编写代码生成工具是程序员的基本功)。

下一篇文章我们将研究怎么生成实体类以及要生成什么样的实体类。

代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐