CodeSmith作为一款非常有用的代码生成工具,成为相当多程序员的钟爱,可事实上很多人对它的使用,仅限于手册介绍,我这里主要介绍三个很有用但网上很难找到的技巧:
1.如何根据子模板,批量生成一批代码文件,并存入用户指定文件夹。
下面是根据用户指定表,生成数据层代码的模板,如下,保存为DataObjectTmp.cst(为减小代码量,我仅保留了插入函数)
<%@ CodeTemplate Language="C#" TargetLanguage="C#" Debug="True" ResponseEncoding="UTF-8" Description="" %> <%@ Assembly Name="SchemaExplorer" %> <%@ Assembly Name="System.Data" %> <%@ Assembly Name="System.Data.OracleClient" %> <%@ Import Namespace="SchemaExplorer" %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.OracleClient" %> <%@ Import Namespace="System.Collections.Specialized" %> <%@ Property Name="Author" Type="String" Category="Context" Default="WenLiu" Optional="True" Description="Author of this unit" %> <%@ Property Name="DataTable" Type="TableSchema" Category="Context" Description="Table name in database" %>
执行该模板,给属性指定一个表,顺利生成代码。
可如果某系统有几十乃至几百个表,难道需要一遍一遍的生成吗,岂不太麻烦?下面来解决这个问题。
新建一个母板,输入如下代码,保存为GenerateAllTmp.cst
<%@ CodeTemplate Language="C#" TargetLanguage="Text" Description="" %> <%@ Register Name="DataObject" Template="C:/Users/wenliu/Documents/CodeSmith/Templates/OracleTier/DataObjectTmp.cst" MergeProperties="False" ExcludeProperties="" %> <%@ Assembly Name="SchemaExplorer" %> <%@ Assembly Name="CodeSmith.BaseTemplates" %> <%@ Import Namespace="CodeSmith.BaseTemplates" %> <%@ Import Namespace="SchemaExplorer" %> <%@ Property Name="Database" Type="DatabaseSchema" Category="Context" Optional="True" Description="If generate by database,please set this property" %>
该模板中,先是对子模板进行注册,然后根据用户指定数据库,循环调用子模板,并每次调用结果写入用户指定文件夹。
2. 解决了批量生成的问题,可是实际中我们的数据库经常在调整,每次调整后都需要重新生成数据层,然和这个时候,可能因为事先生成的数据层方法不够用,我们已经在数据层添加了一些方法,这个时候,如何保留用户添加的代码,只覆盖Smith生成部分? 下面来解决这个问题。
我们对子模板做下修改,如下:
............................. 以上省略部分即(1)中描述的子模板内容 以下部分为新添加部分 //Flag: Auto Generated Over 此行为CodeSmith代码生成标识行 //用户添加代码区 namespace DataAccess { public partial class <%= GetClassName(1) %>:DataBase { } }
然后在对母板稍作修改,如下:
<%@ CodeTemplate Language="C#" TargetLanguage="Text" Description="" %> <%@ Register Name="DataObject" Template="C:/Users/wenliu/Documents/CodeSmith/Templates/OracleTier/DataObject.cst" MergeProperties="False" ExcludeProperties="" %> <%@ Assembly Name="SchemaExplorer" %> <%@ Assembly Name="CodeSmith.BaseTemplates" %> <%@ Import Namespace="CodeSmith.BaseTemplates" %> <%@ Import Namespace="SchemaExplorer" %> <%@ Property Name="Database" Type="DatabaseSchema" Category="Context" Optional="True" Description="If generate by database,please set this property" %>
在母版中,对于新增加表,将直接生成文件,对于已经存在的数据层代码文件,则根据文件中的"Flag"进行代码替换,并保留用户添加代码。
3.还有一个问题,假如用户只想生成单个表的数据层,怎么办呢,没必要对整个数据再重新遍历生成吧?下面再来解决这个问题。
我们对母版修改一下,并给母板加一个DATATABLE属性,如下:
<%@ CodeTemplate Language="C#" TargetLanguage="Text" Description="" %> <%@ Register Name="DataObject" Template="C:/Users/wenliu/Documents/CodeSmith/Templates/OracleTier/DataObject.cst" MergeProperties="False" ExcludeProperties="" %> <%@ Assembly Name="SchemaExplorer" %> <%@ Assembly Name="CodeSmith.BaseTemplates" %> <%@ Import Namespace="CodeSmith.BaseTemplates" %> <%@ Import Namespace="SchemaExplorer" %> <%@ Property Name="Database" Type="DatabaseSchema" Category="Context" Optional="True" Description="If generate by database,please set this property" %> <%@ Property Name="DataTable" Type="TableSchema" Category="Context" Optional="True" Description="If generate by table,please set this property" %>
这个时候,如果用户指定了单个表,则根据指定表进行生成,如果指定的是数据库,则遍历生成整个数据库全部表的数据层代码。
总结:事实上,CODESMITH几乎支持.net下全部的常用函数,上面只是小试牛刀,完全可以根据自己需要任意生成、替换等。