最近学习使用CodeSmith代码生成器

CodeSmith 是一种语法类似于asp.net的基于模板的代码生成器,程序可以自定义模板,从而减少重复编码的劳动量,提高效率。

作用:CodeSmith 是一种基于模板的代码生成工具,它使用类似于ASP.NET的语法来生成任意类型的代码或文本。与其他许多代码生成工具不同,CodeSmith 不要求您订阅特定的应用程序设计或体系结构。使用 CodeSmith,可以生成包括简单的强类型集合和完整应用程序在内的任何东西。

当您生成应用程序时,您经常需要重复完成某些特定的任务,例如编写数据访问代码或者生成自定义集合。CodeSmith 在这些时候特别有用,因为您可以编写模板自动完成这些任务,从而不仅提高您的工作效率,而且能够自动完成那些最为乏味的任务。CodeSmith 附带了许多模板,包括对应于所有 .NET 集合类型的模板以及用于生成存储过程的模板,但该工具的真正威力在于能够创建自定义模板。

应用:CodeSmith 是一种语法类似于asp.net的基于模板的代码生成器,程序可以自定义模板,从而减少重复编码的劳动量,提高效率。

安装CodeSmith 2.6注册后发现有两个可运行程序CodeSmith Studio.exe和CodeSmith Explorer.exe

CodeSmith Studio.exe用来创建自定义模板

CodeSmith Explorer.exe用来导入模板并且生成代码

打开 CodeSmith Studio.exe,新建一个C#模板。发现有如下类似与asp.net的标识符号

<% %>

<%= %>

<%@ %>

<script runat="template"> </script>

官方站点:http://www.codesmithtools.com/

下面是使用CodeSmith常用的方法

 using System;
using SchemaExplorer;
using System.Data;
using CodeSmith.Engine;
using System.Text.RegularExpressions; /// <summary>
/// CodeSmith公用方法类
/// </summary>
public class ToolsCodeTemplate:CodeTemplate
{
#region 获取Molde类名称
/// <summary>
/// 获取Molde类名称
/// </summary>
/// <param name="table">表</param>
/// <returns>表名称(表名称即为Model类名称)</returns>
public string GetModelClassName(TableSchema table)
{
string result;
if ( table.ExtendedProperties.Contains("ModelName") )
{
result = (string)table.ExtendedProperties["ModelName"].Value;
return MakePascal(result);
} if (table.Name.EndsWith("s"))
{
result = MakeSingle(table.Name);
}
else
{
result = table.Name;
} return MakePascal(result);
}
#endregion #region 获取属性名称
/// <summary>
/// 获取属性名称
/// </summary>
/// <param name="column"></param>
/// <returns></returns>
public string GetPropertyName(ColumnSchema column)
{
return MakePascal(GetNameFromDBFieldName(column));
}
#endregion #region 获取从数据库字段得到的名称
/// <summary>
/// 获取从数据库字段得到的名称
/// </summary>
/// <param name="column"></param>
/// <returns></returns>
public string GetNameFromDBFieldName(ColumnSchema column)
{
return column.Name;
}
#endregion #region 获取属性类型
/// <summary>
/// 获取属性类型
/// </summary>
/// <param name="column">列</param>
/// <returns>属性类型</returns>
public string GetPropertyType(ColumnSchema column)
{
return GetCSharpTypeFromDBFieldType(column);
}
#endregion #region 获取主键名称
/// <summary>
/// 获取主键名称
/// </summary>
/// <param name="TargetTable">表</param>
/// <returns>主键名称</returns>
public string GetPKName(TableSchema TargetTable)
{
if (TargetTable.PrimaryKey != null)
{
if (TargetTable.PrimaryKey.MemberColumns.Count == )
{
return TargetTable.PrimaryKey.MemberColumns[].Name;
}
else
{
throw new Exception("This template will not work on primary keys with more than one member column.");
}
}
else
{
throw new Exception("This template will only work on tables with a primary key.");
}
}
#endregion #region 获取主键类型
/// <summary>
/// 获取主键类型
/// </summary>
/// <param name="TargetTable">表</param>
/// <returns>主键类型</returns>
public string GetPKType(TableSchema TargetTable)
{
if (TargetTable.PrimaryKey != null)
{
if (TargetTable.PrimaryKey.MemberColumns.Count == )
{
return GetCSharpTypeFromDBFieldType(TargetTable.PrimaryKey.MemberColumns[]);
}
else
{
throw new ApplicationException("This template will not work on primary keys with more than one member column.");
}
}
else
{
throw new ApplicationException("This template will only work on MyTables with a primary key.");
}
}
#endregion #region 类型转化
/// <summary>
/// 获取数据库类型转化为C#类型
/// </summary>
/// <param name="column">列</param>
/// <returns>C#类型的字符串</returns>
public string GetCSharpTypeFromDBFieldType(ColumnSchema column)
{
if (column.Name.EndsWith("TypeCode")) return column.Name;
string type;
switch (column.DataType)
{
case DbType.AnsiString: type= "string";break;
case DbType.AnsiStringFixedLength: type= "string";break;
case DbType.Binary: type= "byte[]";break;
case DbType.Boolean: type= "bool";break;
case DbType.Byte: type= "byte";break;
case DbType.Currency: type= "decimal";break;
case DbType.Date: type= "DateTime";break;
case DbType.DateTime: type= "DateTime";break;
case DbType.Decimal: type= "decimal";break;
case DbType.Double: type= "double";break;
case DbType.Guid: type= "Guid";break;
case DbType.Int16: type= "short";break;
case DbType.Int32: type= "int";break;
case DbType.Int64: type= "long";break;
case DbType.Object: type= "object";break;
case DbType.SByte: type= "sbyte";break;
case DbType.Single: type= "float";break;
case DbType.String: type= "string";break;
case DbType.StringFixedLength: type= "string";break;
case DbType.Time: type= "TimeSpan";break;
case DbType.UInt16: type= "ushort";break;
case DbType.UInt32: type= "uint";break;
case DbType.UInt64: type= "ulong";break;
case DbType.VarNumeric: type= "decimal";break;
default:
{
type= "__UNKNOWN__" + column.NativeType;//未知
break;
}
}
//是否为Null
if(column.AllowDBNull && column.SystemType.IsValueType)
{
type=type+"?";
}
return type;
}
/// <summary>
/// 获取数据库类型转化为C#类型
/// </summary>
/// <param name="dbType">DbType的类型</param>
/// <returns>C#类型的字符串</returns>
public string GetDBTypeToCSharpType (System.Data.DbType dbType)
{
switch (dbType)
{
case DbType.AnsiString:return "string";
case DbType.AnsiStringFixedLength:return "string";
case DbType.Binary:return "byte[]";
case DbType.Boolean:return "bool";
case DbType.Byte:return "byte";
case DbType.Currency:return "decimal";
case DbType.Date:return "DateTime";
case DbType.DateTime:return "DateTime";
case DbType.DateTime2:return "DateTime";
case DbType.DateTimeOffset:return "DateTime";
case DbType.Decimal:return "decimal";
case DbType.Double:return "double";
case DbType.Guid:return "Guid";
case DbType.Int16:return "short";
case DbType.Int32:return "int";
case DbType.Int64:return "long";
case DbType.Object:return "object";
case DbType.SByte:return "sbyte";
case DbType.Single:return "float";
case DbType.String:return "string";
case DbType.StringFixedLength:return "string";
case DbType.Time:return "DateTime";
case DbType.UInt16:return "ushort";
case DbType.UInt32:return "uint";
case DbType.UInt64:return "ulong";
case DbType.VarNumeric:return "decimal";
case DbType.Xml:return "string";
default:return "object";
}
}
#endregion #region 骆驼命名法,帕斯卡命名法和匈牙利命名法
/// <summary>
/// 获取首字母大写的字符串
/// </summary>
/// <param name="value">字符串(例如:xiangyisheng)</param>
/// <returns>xiangyisheng => Xiangyisheng</returns>
public string MakePascal(string value)
{
return value.Substring(, ).ToUpper() + value.Substring();
}
/// <summary>
/// 获取首字母小写的字符串
/// </summary>
/// <param name="value">字符串(例如:Xiangyisheng)</param>
/// <returns>Xiangyisheng => xiangyisheng</returns>
public string MakeCamel(string value)
{
return value.Substring(, ).ToLower() + value.Substring();
}
/// <summary>
/// 获取小写的字符串
/// </summary>
/// <param name="value">字符串(例如:XiangYiSheng)</param>
/// <returns>XiangYiSheng => xiangyisheng</returns>
public string MakeSmall(string value)
{
return value.ToLower();
}
/// <summary>
/// 获取单数形式的字符串
/// </summary>
/// <param name="name">字符串(例如:Xiangyishengs)</param>
/// <returns>Xiangyishengs => Xiangyisheng</returns>
public string MakeSingle(string name)
{
Regex plural1 = new Regex("(?<keep>[^aeiou])ies$");
Regex plural2 = new Regex("(?<keep>[aeiou]y)s$");
Regex plural3 = new Regex("(?<keep>[sxzh])es$");
Regex plural4 = new Regex("(?<keep>[^sxzhyu])s$"); if(plural1.IsMatch(name))
return plural1.Replace(name, "${keep}y");
else if(plural2.IsMatch(name))
return plural2.Replace(name, "${keep}");
else if(plural3.IsMatch(name))
return plural3.Replace(name, "${keep}");
else if(plural4.IsMatch(name))
return plural4.Replace(name, "${keep}"); return name;
}
/// <summary>
/// 获取复数形式的字符串
/// </summary>
/// <param name="name">字符串(例如:Xiangyisheng)</param>
/// <returns>Xiangyisheng => Xiangyishengs</returns>
public string MakePlural(string name)
{
Regex plural1 = new Regex("(?<keep>[^aeiou])y$");
Regex plural2 = new Regex("(?<keep>[aeiou]y)$");
Regex plural3 = new Regex("(?<keep>[sxzh])$");
Regex plural4 = new Regex("(?<keep>[^sxzhy])$"); if(plural1.IsMatch(name))
return plural1.Replace(name, "${keep}ies");
else if(plural2.IsMatch(name))
return plural2.Replace(name, "${keep}s");
else if(plural3.IsMatch(name))
return plural3.Replace(name, "${keep}es");
else if(plural4.IsMatch(name))
return plural4.Replace(name, "${keep}s"); return name;
}
#endregion #region 打印标题
/// <summary>
/// 打印标题
/// </summary>
public void PrintHeader()
{
Response.WriteLine("//============================================================");
Response.WriteLine("//http://www.cnblogs.com/xiangyisheng");
Response.WriteLine("//============================================================");
Response.WriteLine();
}
#endregion
}

ToolsCodeTemplate

下面是我理解ToolsCodeTemplate测试例子

 <%--
名称:测试模板
作者:长毛象
描述:测试模板
网址:http://www.cnblogs.com/xiangyisheng
--%>
<%@ CodeTemplate Language="C#" TargetLanguage="text" Src="ToolsCodeTemplate.cs" Inherits="ToolsCodeTemplate" Debug="False" Description="测试模板" ResponseEncoding="UTF-8" %>
<%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Default="" Optional="False" Category="Table" Description="源表名" OnChanged="" Editor="" EditorBase="" Serializer="" %>
<%@ Assembly Name="SchemaExplorer" %>
<%@ Import Namespace="SchemaExplorer" %>
<%@ Import Namespace="System.Data" %>
<% PrintHeader(); %> <%--获取Molde类名称 参数:表--%>
获取Molde类名称:<%= this.GetModelClassName(this.SourceTable) %> <%--获取属性名称 参数:列--%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
获取属性名称:<%=this.GetPropertyName(column)%>
<%}%> <%--获取从数据库字段得到的名称 参数:列--%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
获取从数据库字段得到的名称:<%=this.GetNameFromDBFieldName(column)%>
<%}%> <%--获取属性类型 参数:列--%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
获取属性类型:<%=this.GetPropertyType(column)%>
<%}%> <%--获取主键名称 参数:表--%>
获取主键名称:<%= this.GetPKName(this.SourceTable) %> <%--获取主键类型 参数:表--%>
获取主键类型:<%= this.GetPKType(this.SourceTable) %> <%--获取数据库类型转化为C#类型 参数:列--%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
获取数据库类型转化为C#类型:<%=this.GetCSharpTypeFromDBFieldType(column)%>
<%}%> <%--获取数据库类型转化为C#类型2 参数:列类型--%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
获取数据库类型转化为C#类型2:<%=this.GetDBTypeToCSharpType(column.DataType)%>
<%}%> <%--获取首字母大写的字符串 参数:字符串--%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
获取首字母大写的字符串:<%=this.MakePascal(column.Name)%>
<%}%> <%--获取首字母小写的字符串 参数:字符串--%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
获取首字母小写的字符串:<%=this.MakeCamel(column.Name)%>
<%}%> <%--获取小写的字符串 参数:字符串--%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
获取小写的字符串:<%=this.MakeSmall(column.Name)%>
<%}%> <%--获取单数形式的字符串 参数:字符串--%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
获取单数形式的字符串:<%=this.MakeSingle(column.Name)%>
<%}%> <%--获取复数形式的字符串 参数:字符串--%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
获取首字母大写的字符串:<%=this.MakePascal(column.Name)%>
<%}%>

TestTemplate

创建生成实体类的模板,代码如下:

 <%--
Name:实体类
Author: Eason.Xiang
Description:
--%>
<%@ CodeTemplate Language="C#" TargetLanguage="C#" Src="ToolsCodeTemplate.cs" Inherits="ToolsCodeTemplate" Debug="False" Description="生成指定Table的实体类(使用原始方式封装字段(Ctrl+R+E))" ResponseEncoding="UTF-8" %>
<%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Default="" Optional="False" Category="Table" Description="源表名" OnChanged="" Editor="" EditorBase="" Serializer="" %>
<%@ Property Name="NameSpace" Type="System.String" Default="Model" Optional="False" Category="NameSpace" Description="命名空间" OnChanged="" Editor="" EditorBase="" Serializer="" %>
<%@ Property Name="IsFK" Type="System.Boolean" Default="False" Optional="False" Category="Other" Description="是否处理外键" OnChanged="" Editor="" EditorBase="" Serializer="" %>
<%@ Property Name="Author" Type="System.String" Default="Jack.Zhou" Optional="False" Category="Other" Description="" OnChanged="" Editor="" EditorBase="" Serializer="" %>
<%@ Assembly Name="SchemaExplorer" %>
<%@ Assembly Name="System.Data" %>
<%@ Assembly Name="mscorlib" %>
<%@ Import Namespace="SchemaExplorer" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Collections.Generic" %>
<% PrintHeader(); %>
using System;
using System.Collections.Generic;
using System.Text;
namespace <%=this.NameSpace%>
{
/// <summary>
/// 实体类<%=this.GetModelClassName(this.SourceTable)%>
/// </summary>
public class <%=this.GetModelClassName(this.SourceTable)%>
{
#region 私有字段
<%foreach(ColumnSchema column in this.SourceTable.ForeignKeyColumns){%>
<%if(!IsFK){%>
private <%=this.GetCSharpTypeFromDBFieldType(column)%> _<%=this.MakeCamel(column.Name)%>;
<%}else{%>
private <%=this.GetFKClassName(column)%> _<%=this.MakeCamel(column.Name)%>;
<%}%>
<%}%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
private <%=this.GetCSharpTypeFromDBFieldType(column)%> _<%=this.MakeCamel(column.Name)%>;
<%}%>
#endregion #region 公开属性
<%foreach(ColumnSchema column in this.SourceTable.ForeignKeyColumns){%>
<%if(!IsFK){%>
public <%=this.GetCSharpTypeFromDBFieldType(column)%> <%=this.MakePascal(column.Name)%>
{
get{return _<%=this.MakeCamel(column.Name)%>;}
set{_<%=this.MakeCamel(column.Name)%>=value;}
}
<%}else{%>
public <%=this.GetFKClassName(column)%> <%=this.MakePascal(column.Name)%>
{
get{return _<%=this.MakeCamel(column.Name)%>;}
set{_<%=this.MakeCamel(column.Name)%>=value;}
}
<%}%>
<%}%>
<%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%>
public <%=this.GetCSharpTypeFromDBFieldType(column)%> <%=this.MakePascal(column.Name)%>
{
get{return _<%=this.MakeCamel(column.Name)%>;}
set{_<%=this.MakeCamel(column.Name)%>=value;}
}
<%}%>
#endregion
}
}
<script runat="template">
#region 获取外键类名
public string GetFKClassName(ColumnSchema column)
{
foreach(TableKeySchema key in this.SourceTable.ForeignKeys)
{
foreach(MemberColumnSchema fk in key.ForeignKeyMemberColumns)
{
if(fk.Name==column.Name)
{
return this.GetModelClassName(key.PrimaryKeyTable);
}
}
}
return "";
}
#endregion
</script>

TableEntity

CodeSmith截图

好了,目前大概就学到这里了。(原文:http://www.cnblogs.com/xiangyisheng/p/6208637.html)

ToolsCodeTemplate使用的更多相关文章

  1. CodeSmith自己动手写模板

    CodeSmith学习笔记------ 1.新建一个Code Smith Generator Template(C sharp) 2.一些常见标签的解释: ①外部变量: <%@ Property ...

随机推荐

  1. [C#] 进阶 - LINQ 标准查询操作概述

    LINQ 标准查询操作概述 序 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> ...

  2. 深入研究Visual studio 2017 RC新特性

    在[Xamarin+Prism开发详解三:Visual studio 2017 RC初体验]中分享了Visual studio 2017RC的大致情况,同时也发现大家对新的Visual Studio很 ...

  3. Aaron Stannard谈Akka.NET 1.1

    Akka.NET 1.1近日发布,带来新特性和性能提升.InfoQ采访了Akka.net维护者Aaron Stannard,了解更多有关Akka.Streams和Akka.Cluster的信息.Aar ...

  4. C++ 事件驱动型银行排队模拟

    最近重拾之前半途而废的C++,恰好看到了<C++ 实现银行排队服务模拟>,但是没有实验楼的会员,看不到具体的实现,正好用来作为练习. 模拟的是银行的排队叫号系统,所有顾客以先来后到的顺序在 ...

  5. 常用 meta 整理

    <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 --> <meta name="HandheldFriendly" con ...

  6. Android中的沉浸式状态栏效果

    无意间了解到沉浸式状态栏,感觉贼拉的高大上,于是就是试着去了解一下,就有了这篇文章.下面就来了解一下啥叫沉浸式状态栏.传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这一样就在一定 ...

  7. ASP.NET Core MVC 中的 [Controller] 和 [NonController]

    前言 我们知道,在 MVC 应用程序中,有一部分约定的内容.其中关于 Controller 的约定是这样的. 每个 Controller 类的名字以 Controller 结尾,并且放置在 Contr ...

  8. Leetcode 笔记 101 - Symmetric Tree

    题目链接:Symmetric Tree | LeetCode OJ Given a binary tree, check whether it is a mirror of itself (ie, s ...

  9. Async和Await异步编程的原理

    1. 简介 从4.0版本开始.NET引入并行编程库,用户能够通过这个库快捷的开发并行计算和并行任务处理的程序.在4.5版本中.NET又引入了Async和Await两个新的关键字,在语言层面对并行编程给 ...

  10. What is Away3D

    做了几个基于Flash平台的3D的项目,一路走来收获颇多.Away3D作为一个开源的Flash3D引擎,在3D页游领域,无疑是当前OGRE在国内的地位. 翻译出了多年前做Away3D中国社区的时候翻译 ...