少见但绝对实用的CodeSmith使用技巧

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" %> <% PrintHeader(); %> using System; using System.Data; using System.Text; using System.Data.OracleClient; namespace DataAccess { ///

/// The data module of <%= this.DataTable.Name %> /// public class <%= GetClassName(0) %> { public <%= GetClassName(0) %>() { } #region Field Attribute <% for(int i=0;i<=DataTable.Columns.Count-1;i++)%> <% {%> private <%= DataTable.Columns[i].SystemType%> m<%= DataTable.Columns[i].Name %>; <% }%> <% for(int i=0;i<=DataTable.Columns.Count-1;i++)%> <% {%> public <%= DataTable.Columns[i].SystemType%> <%= DataTable.Columns[i].Name %> { get { return m<%= DataTable.Columns[i].Name %>; } set { m<%= DataTable.Columns[i].Name %>=value; } } <% }%> #endregion } /// /// The data object of <%= this.DataTable.Name %> /// public partial class <%= GetClassName(1) %>:DataBase { private string strErr = string.Empty; #region Field Attribute private <%= GetClassName(0) %> Data=new <%= GetClassName(0) %>(); <% for(int i=0;i<=DataTable.Columns.Count-1;i++)%> <% {%> public <%= DataTable.Columns[i].SystemType%> <%= DataTable.Columns[i].Name %> { get { return Data.<%= DataTable.Columns[i].Name %>; } set { Data.<%= DataTable.Columns[i].Name %>=value; } } <% }%> #endregion public <%= GetClassName(1) %>() { } /// /// Delete current record /// /// public Boolean Delete(out string strError) { strError = string.Empty; string strSql="<%= GetDeleteSql(DataTable) %>"; try { <% if (DataTable.HasPrimaryKey)%> <%{%> OracleParameter[] objParameter = new OracleParameter[<%= DataTable.PrimaryKey.MemberColumns.Count %>]; <% for(int i=0;i<=DataTable.PrimaryKey.MemberColumns.Count-1;i++)%> <% {%> objParameter[<% =i %>] = new OracleParameter("<%= DataTable.PrimaryKey.MemberColumns[i].Name %>",OracleType.<%= GetSqlTypeFormDBType(DataTable.PrimaryKey.MemberColumns[i].DataType) %>); objParameter[<% =i %>].Value = this.<%= DataTable.PrimaryKey.MemberColumns[i].Name %>; <% }%> <% }%> if(!ExecCmdBySql(strSql,objParameter, out strErr)) throw new Exception(strErr); ClearValue(); } catch (Exception e) { strError = e.Message; return false; } return true; } } }

执行该模板,给属性指定一个表,顺利生成代码。

可如果某系统有几十乃至几百个表,难道需要一遍一遍的生成吗,岂不太麻烦?下面来解决这个问题。

新建一个母板,输入如下代码,保存为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" %> <% OutputSubTemplate(); %>

该模板中,先是对子模板进行注册,然后根据用户指定数据库,循环调用子模板,并每次调用结果写入用户指定文件夹。

 

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" %> <% OutputSubTemplate(); %>

在母版中,对于新增加表,将直接生成文件,对于已经存在的数据层代码文件,则根据文件中的"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" %> <% OutputSubTemplate(); %>

这个时候,如果用户指定了单个表,则根据指定表进行生成,如果指定的是数据库,则遍历生成整个数据库全部表的数据层代码。

 

总结:事实上,CODESMITH几乎支持.net下全部的常用函数,上面只是小试牛刀,完全可以根据自己需要任意生成、替换等。

你可能感兴趣的:(少见但绝对实用的CodeSmith使用技巧)