CodeSmith教程(3) 自动生成Yii Framework ActiveRecord2013-01-19 csdn mapdigit上例介绍了使用CodeSmith编写代码模板的基本方法,本例实现一个较为实用的代码模板,通过数据库自动为Yii Framework 生成所需要的ActiveRecord 类。本例通过修改Yii Framework 开发教程(26) 数据库-Active Record示例 ,原例是手工编写 Employee.php ActiveRecord。首先为工程添加一个C#项目(任意类型,我们只是利用这个项目来包含CodeSmith项目) ,然后添加一个CodeSmith项目和一个CodeSmith模板。然后参考CodeSmith 使用教程(1): 概述 使用Schema Explorer 添加一个 数据连接,本例连接到Chinook数据库:

创建的代码模板 PhpActiveRecord.cst 定义个属性TableName(数据库表名),复制Yii Framework 开发教程(26) 数据库-Active Record示例中Employee.php的定义并使用属性,代码如下:
<%@ Template Language="C#" TargetLanguage="PHP" Debug="False" %> <%@ Property Name="TableName" Type="System.String" Description="Table name" %> <?php class <%= TableName %> extends CActiveRecord { public static function model($className=__CLASS__) { return parent::model($className); } public function tableName() { return "<%= TableName %>"; } } ?><script runat="template"> public override string GetFileName() { return TableName + ".php" ; } </script>这时就可以通过定义TableName 的属性给任意数据表生成对应的ActiveRecord PHP类了。 不过这还 是要手工来一个一个来配置表名。 本例通过一个主模板和一个从模板的方式通过连接数据库自动为所有的表生成对应的 ActiveRecord使用主从模板的具体用法后面再介绍,简单的说子模板相当于子函数,主模板类似于主函数可以调用子函数, 主模板通过调用子模板,传给子模板属性从而可以生成多个文件。创建一个代码模板YiiDataModel.cst 作为主模板,使用子 模板首先需要在主模板中进行注册才能使用:
<%@ Register Name="ActiveRecord" Template="PhpActiveRecord.cst" MergeProperties="false"%>
完整代码如下:
<%@ CodeTemplate Language="C#" TargetLanguage="Text" Description="List all database tables" %> <%@ Import Namespace="System.IO" %> <%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" Category="Context" Description="Database containing the tables." %> <%@ Register Name="ActiveRecord" Template="PhpActiveRecord.cst"MergeProperties="false"%> <%@ Assembly Name="SchemaExplorer" %> <%@ Import Namespace="SchemaExplorer" %> <script runat="template"> public string FirstLetterToUpper(string str) { if (str != null) { if(str.Length > 1) return char.ToUpper(str[0]) + str.Substring(1); else return str.ToUpper(); } return str; } </script> <% for (int i = 0; i < SourceDatabase.Tables.Count; i++) { %><%string name= FirstLetterToUpper(SourceDatabase.Tables[i].Name); %><%string filename= @"../ActiveRecordDemo/protected/models/"+name+".php"; %>// instantiate the sub-template <%ActiveRecord activeRecord = this.Create<ActiveRecord>();%> <%activeRecord.TableName= name; %> <%activeRecord.RenderToFile(filename,true); %> <% } %>