如何使用CodeSmith批量生成代码

在上一篇我们已经用PowerDesigner创建好了需要的测试数据库,下面就可以开始用它完成批量代码生成的工作啦.

下面我会一步步的解释如何用CodeSmith实现预期的结果的,事先声明一下,在此只做一个简单的Demo,并不详细的讲解CodeSmith各个强大的功能,有兴趣的朋友可以打开CodeSmith的帮助文档了解.我只做个抛砖引玉,希望能激起大家更多思想的火花~

先看看CodeSmith的工作原理:

简单的说:CodeSmith首先会去数据库获取数据库的结构,如各个表的名称,表的字段,表间的关系等等,之后再根据用户自定义好的模板文件,用数据库结构中的关键字替代模板的动态变量,最终输出并保存为我们需要的目标文件.好,原理清楚了,就开始实践吧:

1. 运行CodeSmith,可以看到如下界面:

2. CodeSmith是创建模板的地方,首先当然是创建一个模板啦,点击工具栏最左边的New DocumentC# Template,如图所示:

3. 点击运行按钮,运行结果如下:

好,我们来分析为什么会得到这样的运行结果吧,点击运行窗口左下角的Template按钮返回模板设计窗口,可以发现,只要是没有被<%%>或者<scriptrunat="template"></script>包含的文字均被直接输出了,这些以后就要被换成我们分层架构中一些一成不变的模板代码:

4. 好了,简单了解啦一些CodeSmith的代码结构,下面就开始用它来生成我们的分层代码吧,在此我就不介绍分层架构的概念了,不然就偏离主题了.为了能更简单明了的说明,我们在此就只用CodeSmith生成分层架构的实体层吧.先看看如果我们不使用CodeSmith需要手动敲出哪些代码:

Major.cs

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Entity
{
public partial class
Major
{
public Int32 MajorID{ get;set; }
public String Name{ get;set; }
public String Remark{ get;set; }
}
}

Student.cs

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Entity
{
public partial class
Student
{
public String StudentID{ get;set; }
public Int32 MajorID{ get;set; }
public String Name{ get;set; }
public Boolean Sex{ get;set; }
public Int32 Age{ get;set; }
public String Remark{ get;set; }
}
}

我将两个文件中重复的代码使用黄色背景色加深了,我们可以发现,如果每个表都要通过手动创建,那么将有大量的代码(黄色背景)需要复制粘贴操作,这些操作是繁琐而没有任何意义的.因此,我们会希望将黄色背景部分的代码做成模板,而其他变化的代码由数据库的结构动态生成,如此一来,我们就不用再为这些烦人的复制粘贴操作懊恼了.

5. 那么就开始我们的实践吧,就在刚刚创建好的文件开始吧,先随意保存到一个目录下,命名为test.cst,接着删除多余的代码,只保留第一行,该行表明我们的模板使用何种语言,这里我们使用C#.

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><%@ CodeTemplateLanguage="C#" TargetLanguage="Text" Src="" Inherits=""Debug="False" CompilerVersion="v3.5"Description="Template description here." %>

6. 参照CodeSmith的工作原理,我们首先要为CodeSmith提供一个数据库,要怎么使它和SQL Server 2005关联起来呢?只要加上下面的代码就行了:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><%-- 加载访问数据库的组件SchemaExplorer,并声明其使用的命名空间 --%>
<%@ AssemblyName="SchemaExplorer" %>
<%@ ImportNamespace="SchemaExplorer" %>

<%-- 数据库 --%>
<%@ PropertyName="SourceDatabase"DeepLoad="True" Optional="False" Category="01. GettingStarted - Required" Description="Database that the tables views, and storedprocedures should be based on. IMPORTANT!!! If SourceTables and SourceViews areleft blank, the Entire Database will then be generated." %>

7. 好了,有了数据库连接,接着还需要一个模板,为了便于管理,我们新建一个文件用于设计模板,FileNewBlank Template,并添加如下代码,最好保存到test.cst所在的文件夹内,命名为Entity.cst:

<%@ CodeTemplateInherits="CodeTemplate"TargetLanguage="Text" Description="NetTiers main template."Debug="True" ResponseEncoding="UTF-8"%>

<%@ AssemblyName="SchemaExplorer" %>
<%@ ImportNamespace="SchemaExplorer" %>

<%-- 要打印的表 --%>
<%@ PropertyName="Table" DeepLoad="True"Optional="False" Category="01. Getting Started - Required"Description="Database that the tables views, and stored procedures shouldbe based on. IMPORTANT!!! If SourceTables and SourceViews are left blank, theEntire Database will then be generated." %>

接着继续添加如下代码:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Entity
{
public partial class <%= Table.Name%>
{
<% foreach(ColumnSchema col inTable.Columns){ %>
public <%= col.DataType %> <%=col.Name %>{ get;set; }
<% } %>
}
}

<%=Table.Name%> 表示在此处输出表的名称

<%foreach(ColumnSchema col in Table.Columns){ %> <% } %> 为循环语句,在{}循环输出列信息.

<%=col.DataType %> 表示在此处输出列的类型

<%=col.Name %> 表示在此处输出列的名称

如图所示:

8. 模板创建好后,要在test.cst文件中注册一下,不然人家怎么知道有你这么一个模板存在呀,在test.cst文件继续输入如下代码:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><%-- 注册实体层Entity模板 --%>
<%@ RegisterName="EntityTemplate" Template=" Entity.cst"MergeProperties="Flase" ExcludeProperties=""%>

9. 好了,模板注册好了,根据CodeSmith工作原理,我们要结合模板和数据库结构来批量生成代码啦,但是我们生成的目标文件要输出到哪里呢?这时我们会需要一个用户自定义属性,用于设置目标文件的输出目录,在test.cst文件的末尾输入如下代码:

代码
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><script runat="template">
//解决方案输出路径
private string Directory = String.Empty;

[Editor(
typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
[Optional, NotChecked]
[DefaultValue(
"")]
public string OutputDirectory
{
get
{
return Directory;
}
set
{
if (value.EndsWith("//")) value = value.Substring(0, value.Length - 1);
Directory
= value;
}
}
</script>

10. 现在连输出目录也有了,该想办法写些函数来完成将数据库架构传递给模板的工作啦,在test.cst文件的末尾输入如下代码:

代码
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><script runat="template">
//生成实体Entity类
private void GenerateEntityClasses()
{
CodeTemplate Template
= new EntityTemplate();
foreach(TableSchema table in this.SourceDatabase.Tables)
{
string FileDirectory = OutputDirectory + "//" + table.Name + ".cs";
//生成模板
Template.SetProperty("Table",table);
//文件输出
Template.RenderToFile(FileDirectory,true);
Debug.WriteLine(FileDirectory
+" 创建成功.");
}
}
</script>

CodeTemplateTemplate = new EntityTemplate();  就是创建了一个新的模板

foreach(TableSchematable in this. SourceDatabase.Tables){} 表示循环输出数据库中的表

Template.SetProperty("Table",table); 就是向模板设置属性,还记得我们在Entity.cst里面设置了一个Table属性吗,我们就是通过这个方法给这个属性设值的.

Template.RenderToFile(FileDirectory,true); 表示将Temlate里的内容全部输出到FileDirectory目录中,true表示如果文件存在直接覆盖.

11. 函数写好了,离成功不远啦,我们在test.cst的最后再添加如下代码,用于调用刚刚写好的函数.至此,模板文件的制作已经完成.

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><%
//创建实体层Entity类
this.GenerateEntityClasses();

Debug.WriteLine(
"OK");
%>

12. 好啦,现在只要设置我们要导出的数据库和输出目录就可以运行看结果啦,点击CodeSmith主窗体右下角Properities面板中SourceDatabase属性栏右侧的…按钮,弹出数据库设置对话框,我们要在此添加一个新的数据库连接:

13. 点击Add按钮,属性设置如图,我们选择的是在前一章用PowerDesigner创建好的PD_test数据库:

14. 点击OK,回到数据库选择对话框,选择刚刚创建好的数据库连接:

15. 接着是设置目标文件输出目录,我在这里设置为桌面的一个新建文件夹:

16. OK,万事俱备,可以点击运行按钮让CodeSmith为我们批量生成代码啦:

打开生成的文件,就可以看到我们期待看到的代码啦:

好了,这些是基础,但是只要你掌握了这些就可以开始自己的CodeSmith之旅啦,我也只能送大家到此咯~其他更多的知识点希望大家能自行查看帮助文章或者上网查询,很高兴又和大家分享了自己的一点心得,接下来想再回头复习一下设计模式,也打算写一些文章,欢迎大家关注~

上述实践中的文件源代码:

test.cst
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><%--
作者:黄聪
网址:http:
//www.cnblogs.com/huangcong
--%>
<%@ CodeTemplate Inherits="CodeTemplate" Language="C#" TargetLanguage="Text" Description="NetTiers main template." Debug="True" ResponseEncoding="UTF-8"%>


<%-- 注册实体层Entity模板 --%>
<%@ Register Name="EntityTemplate" Template="WinformTier/Entity.cst" MergeProperties="Flase" ExcludeProperties=""%>


<%-- 数据库 --%>
<%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" DeepLoad="True" Optional="False" Category="01. Getting Started - Required" Description="Database that the tables views, and stored procedures should be based on. IMPORTANT!!! If SourceTables and SourceViews are left blank, the Entire Database will then be generated." %>


<%
//创建实体层Entity类
this.GenerateEntityClasses();

Debug.WriteLine(
"OK");
%>

<script runat="template">
//生成实体Entity类
private void GenerateEntityClasses()
{
CodeTemplate Template
= new EntityTemplate();
foreach(TableSchema table in this.SourceDatabase.Tables)
{
string FileDirectory = OutputDirectory + "//" + table.Name + ".cs";
//生成模板
Template.SetProperty("Table",table);
//文件输出
Template.RenderToFile(FileDirectory,true);
Debug.WriteLine(FileDirectory
+" 创建成功.");
}
}
</script>


<script runat="template">
//解决方案输出路径
private string Directory = String.Empty;

[Editor(
typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
[Optional, NotChecked]
[DefaultValue(
"")]
public string OutputDirectory
{
get
{
return Directory;
}
set
{
if (value.EndsWith("//")) value = value.Substring(0, value.Length - 1);
Directory
= value;
}
}
</script>

Entity.cst
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><%--
作者:黄聪
网址:http:
//www.cnblogs.com/huangcong
--%>
<%@ CodeTemplate Inherits="CodeTemplate" Language="C#" TargetLanguage="Text" Description="NetTiers main template." Debug="True" ResponseEncoding="UTF-8"%>

<%@ Assembly Name="SchemaExplorer" %>
<%@ Import Namespace="SchemaExplorer" %>

<%@ Property Name="Table" Type="TableSchema" DeepLoad="True" Optional="False" Category="01. Getting Started - Required" Description="Database that the tables views, and stored procedures should be based on. IMPORTANT!!! If SourceTables and SourceViews are left blank, the Entire Database will then be generated." %>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Entity
{
public partial class <%= Table.Name%>
{
<% foreach(ColumnSchema col in Table.Columns){ %>
public <%= col.DataType %> <%= col.Name %>{ get;set; }
<% } %>
}
}

出处:http://www.cnblogs.com/huangcong/archive/2010/06/14/1758201.html 请输

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。


哇,期考啦,怎么那么多考试啊~~~~快看书才行了~~~~

来源:网络


智能推荐

如何使用AbstractProcessor在编译时生成代码

如何使用AbstractProcessor在编译时生成代码 在现阶段的Android开发中,注解越来越流行起来,比如ButterKnife,Retrofit,Dragger,EventBus等等都选择使用注解来配置。按照处理时期,注解又分为两种类型,一种是运行时注解,另一种是编译时注解,运行时注解由于性能问题被一些人所诟病。编译时注解的核心依赖APT(Annotation Processing T...

如何使用Database2Sharp进行代码生成

目录 1.       总体介绍............................................................................................................... 2.      ...

如何使用CslaGen生成CSLA DAL层代码

原文:How to Use CslaGen to Generate CSLA Data Access Layer Code   最近用起了csla,这东东没个代码生成感觉很不方便。找到了CslaGen这个工具, 优点嘛,1,图形化界面,设计BO方便;2,设计文档用xml保存,便于管理。 缺点嘛,只有DAL层的代码,权限、验证这些还得找其他模板了   本示例中的cslagen版本...

使用maven 如何生成源代码的jar包

如何使用maven 打包源代码呢?  方式一:  打开cmd命令行,进入项目所在路径,运行  mvn source:jar  方式二:使用IDE,如eclipse  步骤:  (1)右键点击项目,“Run as”,选择“Maven build...”,如下图  运行结果: ...

使用maven 如何生成源代码的jar包

如何使用maven 打包源代码呢?  方式一:  打开cmd命令行,进入项目所在路径,运行  mvn source:jar  方式二:使用IDE,如eclipse  步骤:  (1)右键点击项目,“Run as”,选择“Maven build...”,如下图  运行结果: ...

猜你喜欢

如何使用代码生成器?(****)

**1. 2. 3.打开这个generatorConfig.xml,打开编写方式。 4.把这里面的路径改成(下面图片框选的红色标记) 5.第一个里面添加完路径还要在后面加上mysql-connector-java-5.1.30.jar 6.打开执行命令,复制里面的xml 7.复制完打开cmd,复制运行这个xml是否成功。 8.如果成功,就会出现代码生成器。 9.这个时候,我们需要的代码生成器直接放...

IDEA如何安装使用代码生成器EasyCode

一.联网环境下IDEA安装该插件步骤。 1.打开IDEA,File-> Setteings->Plugins->Browse Repositories,在Browse Repositories搜索栏搜索easy code,然后安装。 2.安装完成后点击Restart IntelliJ IDEA。 二.非联网环境下IDEA安装该插件步骤。 1.去https://gitee.com/...

lvm逻辑卷管理

       Lvm的重点在于可以弹性的调整filesystem的大小容量,而不是在于数据的存储安全和存储效率上,那么为什么会用到逻辑卷呢?有这样一种情况,在刚开始规划主机的时候/目录只分给20G 所有用户的家目录都在/目录下挂载,如果把用户的家目录迁移出来单独挂载,把原来的家目录的数据完整的复制过来,然后再将/的家目录删除掉,重新挂载到新的分区。如果数据少...

想要学习区块链编程,该掌握哪些计算机语言?

随着区块链技术的声名远扬,行业内科研人员对于区块链技术在应用层面的探索也越来越深入,从区块链的整体架构来看,协议层,扩展层,应用层之间的逻辑设计都少不了编程语言的支撑,那么今天来普及一下,区块链技术应用设计会用到哪些编程语言? 1,C/C++ C/C++语言几乎是所有代码工程师的入门语言,在区块链技术架构中的协议层当中,需要编写很多的数学运算,其中加密解密的哈希函数、高精度的数值运算,而且还要求代...

数据结构与算法之美(笔记22)贪心算法

如何理解“贪心算法”? 假设我们有一个可以容纳100kg物品的背包,可以装各种物品。我们有以下5种豆子,每种豆子的总量和总价值都不一样。为了让背包中所装物品的总价值最大,我们应该在背包中装哪些豆子?豆子又该装多少? 我们只要算一算每个物品的单价,按照单价由高到低依次来装就好了。单价依次是:黑豆,绿豆,红豆,青豆,黄豆。所以,我们在背包中装20kg黑豆,30kg绿豆,50kg...

问答精选

Mathematical method for multiple document clustering by Cosine Similarity

Cosine Similarity: is often used when comparing two documents against each other. It measures the angle between the two vectors. If the value is zero the angle between the two vectors is 90 degrees an...

refresh div not whole page

Here is my code: main.php: when I click submit button which contain in menage member main.php.the whole page will be refreshed. Look around for AJAX tutorials and you'll find an answer. You can't do t...

Unable to update my App programmatically in Win8 - mfc

I am trying to update my App from the sysMenu. And by doing click on Update App.. in the SysMenu, Updates automatically started. Its working fine with XP and Win 7, But when I trying to do the same th...

Why is GetFormattedValue called on a DataGridViewCell that doesn't seem to be properly initialized?

I have created a custom class that inherits from DataGridViewTextBoxCell. In this class I have overridden the GetFormattedValue function. The second parameter to GetFormattedValue is - according to th...

AttributeError on Oandapy API

I'm trying to do "100 lines of python code" for algorithmic trading and have been stopped early in my tracks with an attribute error. I'm using sublime text and running it on python 3.7. Her...

相关问题

相关文章

热门文章

推荐文章

相关标签

推荐问答