一个简单的代码生成器(T4文本模板运用)
说要写这篇文章有一段时间了,但因为最近各方面的压力导致心情十二分的不好,下班后往往都洗洗睡了。今天痛定思痛,终于把这件拖了很久的事做了。好,不废话了,现在看看"一个简单的代码生成器" .
先看看界面吧!

简约到如此,说是代码生成器,估计是要被吐槽的。好吧,借用园子里博友的说法,这只是一粒粟子,如果你愿意,你能看到代码生成器的“种子”。
这样运行的!

画了个简图已描述这个简单的代码生成器的工作过程。下面的介绍将以此图展开:
1)读取数据表的信息:从数据库中读取数据表的信息并转换成要为T4文本模板引擎提供的数据(EntityClassInfo);
2)将要为T4文本模板引擎提供的数据(EntityClassInfo)作为参数传递给T4文本模板引擎(其实是T4文本模板引擎的宿主,详见T4文本模板转换过程);
3)T4文本模板引擎读取模板;
4)T4文本模板引擎将生成的文本返回给应用程序。
代码:
一、在应用程序和代码中传递的参数的类型
1)EntityClassInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace EntityInfo
{
[Serializable]
public class EntityClassInfo
{
public EntityClassInfo(DataTable dt)
{
this.ClassName = dt.TableName;
List<EntityClassPropertyInfo> ropertyListTemp = new List<EntityClassPropertyInfo>();
foreach (DataColumn dcol in dt.Columns)
{
ropertyListTemp.Add(new EntityClassPropertyInfo(dcol));
}
this.RopertyList = ropertyListTemp;
List<EntityClassPropertyInfo> primaryKeyListTemp = new List<EntityClassPropertyInfo>();
List<EntityClassPropertyInfo> notPrimaryKeyListTemp = new List<EntityClassPropertyInfo>(ropertyListTemp);
foreach (DataColumn dcol in dt.PrimaryKey)
{
primaryKeyListTemp.Add(new EntityClassPropertyInfo(dcol));
notPrimaryKeyListTemp.Remove(new EntityClassPropertyInfo(dcol));
}
this.PrimaryKeyList = primaryKeyListTemp;
this.NotPrimaryKeyList = notPrimaryKeyListTemp;
}
public string ClassName
{
get;
private set;
}
public List<EntityClassPropertyInfo> RopertyList
{
get;
private set;
}
public List<EntityClassPropertyInfo> PrimaryKeyList
{
get;
private set;
}
public List<EntityClassPropertyInfo> NotPrimaryKeyList
{
get;
private set;
}
}
}
2)EntityClassPropertyInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace EntityInfo
{
[Serializable]
public class EntityClassPropertyInfo
{
public EntityClassPropertyInfo(DataColumn dcol)
{
this.PropertyName = dcol.ColumnName;
this.PropertyType = dcol.DataType.Name;
this.IsValueType = false;
if (dcol.DataType.IsValueType)
{
if (dcol.AllowDBNull)
{
this.PropertyType = this.PropertyType + "?";
}
else
{
this.IsValueType = true;
}
}
}
public string PropertyName
{
get;
private set;
}
public string PropertyType
{
get;
private set;
}
public bool IsValueType
{
get;
private set;
}
public override bool Equals(object obj)
{
EntityClassPropertyInfo temp = obj as EntityClassPropertyInfo;
if (this.PropertyName == temp.PropertyName && this.PropertyType == temp.PropertyType)
{
return true;
}
return false;
}
}
}
二、模板
1)生成实体类的模板:Entity.tt
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".txt" #>
<#@ import namespace="EntityInfo" #>
<#@ parameter type="EntityInfo.EntityClassInfo" name="entity" #>
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
/// <summary>
/// <#= entity.ClassName#> 的摘要说明
/// </summary>
public class <#= entity.ClassName#>
{
public <#= entity.ClassName#>()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
<# foreach(EntityClassPropertyInfo property in entity.RopertyList)
{ #>
private <#= property.PropertyType#> m_<#= property.PropertyName#>;
<#;
}
#>
<# foreach(EntityClassPropertyInfo property in entity.RopertyList)
{ #>
public <#= property.PropertyType#> <#= property.PropertyName#>
{
set { m_<#= property.PropertyName#> = value; }
get { return m_<#= property.PropertyName#>; }
}
<#;
}
#>
}
2)生成DAL层的模板:DataAccess.tt
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".txt" #>
<#@ import namespace="EntityInfo" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ parameter type="EntityInfo.EntityClassInfo" name="entity" #>
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using MySql.Data.MySqlClient;
using System.Collections.Generic;
/// <summary>
/// <#= entity.ClassName#> 的摘要说明
/// </summary>
public class <#= entity.ClassName#>DAL
{
public <#= entity.ClassName#>DAL()
{
}
#region 私有方法
#region 根据实体类获取MySqlParameter数组 +MySqlParameter[] FromModel(<#= entity.ClassName#> model)
private static MySqlParameter[] FromModel(<#= entity.ClassName#> model)
{
List<MySqlParameter> parameterList = new List<MySqlParameter>();
<# foreach(EntityClassPropertyInfo property in entity.RopertyList)
{
#> parameterList.Add(new MySqlParameter("@<#=property.PropertyName#>", SQLHelper.ToDBValue(model.<#=property.PropertyName#>)));
<#;
}
#>
return parameterList.ToArray();
}
#endregion
#region 将dr中的数据转换为实体类对象 + <#= entity.ClassName#> ToModel(DataRow dr)
private static <#= entity.ClassName#> ToModel(DataRow dr)
{
<#= entity.ClassName#> model = new <#= entity.ClassName#>();
<# foreach(EntityClassPropertyInfo property in entity.RopertyList)
{
if(property.IsValueType)
{
#> model.<#=property.PropertyName#> = Convert.To<#= property.PropertyType#>(SQLHelper.FromDBValue(dr["<#= property.PropertyName #>"]));
<#;
}
else
{
#> model.<#=property.PropertyName#> = SQLHelper.FromDBValue(dr["<#=property.PropertyName#>"]) as <#=property.PropertyType#>;
<#;
}
}
#>
return model;
}
#endregion
#endregion
#region 增 + int Insert(<#= entity.ClassName#> model)
public static int Insert(<#= entity.ClassName#> model)
{
int result = -1;
string sql = @"INSERT INTO <#= entity.ClassName#>(<#= string.Join(",",GetSqlInsertInto()) #>)
VALUES(<#= string.Join(",",GetSqlInsertValue()) #>);";
result = SQLHelper.ExecuteNonQuery(sql,FromModel(model));
return result;
}
#endregion
#region 删 + int DeleteById(<#= string.Join(",",GetSqlDelVariable()) #>)
public static int DeleteById(<#= string.Join(",",GetSqlDelVariable()) #>)
{
int result = -1;
string sql = @"DELETE FROM <#= entity.ClassName#> WHERE <#= string.Join(" AND ",GetSqlWhereId()) #>;";
result = SQLHelper.ExecuteNonQuery(sql,<#= string.Join(",",GetSqlDelParameter()) #>);
return result;
}
#endregion
#region 改 + int Update(<#= entity.ClassName#> model)
public static int Update(<#= entity.ClassName#> model)
{
int result = -1;
string sql = @"UPDATE <#= entity.ClassName#>
SET <#= string.Join(",",GetSqlUpdateSet()) #>
WHERE <#= string.Join(" AND ",GetSqlWhereId()) #>";
result = SQLHelper.ExecuteNonQuery(sql, FromModel(model));
return result;
}
#endregion
#region 查 + int GetCountAll()
public static int GetCountAll()
{
int result = 0;
string sql = @"SELECT Count(*) FROM <#= entity.ClassName#>;";
result = Convert.ToInt32(SQLHelper.ExecuteScalar(sql));
return result;
}
#endregion
#region 查 + List<<#= entity.ClassName#>> GetBySql(string sql,params MySqlParameter[] parameters)
public static List<<#= entity.ClassName#>> GetBySql(string sql,params MySqlParameter[] parameters)
{
List<<#= entity.ClassName#>> modelList = new List<<#= entity.ClassName#>>();
DataTable dt = SQLHelper.ExecuteDataTable(sql,parameters);
foreach (DataRow dr in dt.Rows)
{
modelList.Add(ToModel(dr));
}
return modelList;
}
#endregion
}
<#+
private string[] GetSqlInsertInto()
{
List<string> propertyNameList= new List<string>();
foreach(EntityClassPropertyInfo property in entity.RopertyList)
{
propertyNameList.Add(property.PropertyName);
}
return propertyNameList.ToArray();
}
private string[] GetSqlInsertValue()
{
List<string> propertyNameList= new List<string>();
foreach(EntityClassPropertyInfo property in entity.RopertyList)
{
propertyNameList.Add("@" + property.PropertyName);
}
return propertyNameList.ToArray();
}
private string[] GetSqlDelVariable()
{
List<string> propertyList= new List<string>();
foreach(EntityClassPropertyInfo property in entity.PrimaryKeyList)
{
propertyList.Add(property.PropertyType + " m_" + property.PropertyName);
}
return propertyList.ToArray();
}
private string[] GetSqlDelParameter()
{
List<string> propertyList= new List<string>();
foreach(EntityClassPropertyInfo property in entity.PrimaryKeyList)
{
propertyList.Add("new MySqlParameter(@\"" + property.PropertyName + "\" ,m_" + property.PropertyName + ")");
}
return propertyList.ToArray();
}
private string[] GetSqlUpdateSet()
{
List<string> propertyList= new List<string>();
foreach(EntityClassPropertyInfo property in entity.NotPrimaryKeyList)
{
propertyList.Add(property.PropertyName +"=@" + property.PropertyName);
}
return propertyList.ToArray();
}
private string[] GetSqlWhereId()
{
List<string> propertyList= new List<string>();
foreach(EntityClassPropertyInfo property in entity.PrimaryKeyList)
{
propertyList.Add(property.PropertyName +"=@" + property.PropertyName);
}
return propertyList.ToArray();
}
#>
三、代码生成四步走:
1)从数据表信息 =》EntityClassInfo:
DataTable dt = SQLHelper.ExecuteDataTable(SQLHelper.GetConnectionString(), string.Format("SELECT * FROM {0} LIMIT 0,0", cbbTableName.SelectedValue.ToString()));
EntityClassInfo entityInfo = new EntityClassInfo(dt);
备注:
#region ExecuteTable方法
public static DataTable ExecuteDataTable(string connectionString,string sql, params MySqlParameter[] parameters)
{
using (MySqlConnection conn = new MySqlConnection(connectionString))
{
using(MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
{
using (DataTable dt = new DataTable())
{
da.Fill(dt);
da.FillSchema(dt, SchemaType.Source); //从数据源中检索架构
return dt;
}
}
}
}
}
#endregion
2)给T4文本模板传参:
CustomTextTemplatingEngineHost host = new CustomTextTemplatingEngineHost();
host.Session = new TextTemplatingSession();
host.Session.Add("entity", classInfo);
3)读取文本模板:
string input = File.ReadAllText(templatePath);
string output = new Engine().ProcessTemplate(input, host);
4)返回生成的文本:
string output = new Engine().ProcessTemplate(input, host);
源码下载(VS2010项目):一个简单的代码生成器(T4文本模板运用)
一个简单的代码生成器(T4文本模板运用)的更多相关文章
- 编写 T4 文本模板
文本模板由以下部件组成: 1)指令 - 控制模板处理方式的元素. 2)文本块 - 直接复制到输出的内容. 3)控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码. 指令: 指令是控制模板 ...
- T4 文本模板编写准则
如果要在 Visual Studio 中生成程序代码或其他应用程序资源,遵守以下一般准则可能非常有帮助. 它们并不是一成不变的规则. 设计时 T4 模板准则 设计时 T4 模板是在设计时在 Visua ...
- 使用 T4 文本模板生成设计时代码
使用设计时 T4 文本模板,您可以在 Visual Studio 项目中生成程序代码和其他文件. 通常,您编写一些模板,以便它们根据来自模型的数据来改变所生成的代码. 模型是包含有关应用程序要求的 ...
- T4文本模板转换过程
T4文本模板转换过程将文本模板文件作为输入,生成一个新的文本文件作为输出. 例如,可以使用文本模板生成 Visual Basic 或 C# 代码,还可以生成 HTML 报告. 有三个组件参与这一过程: ...
- 动手写一个简单的Web框架(模板渲染)
动手写一个简单的Web框架(模板渲染) 在百度上搜索jinja2,显示的大部分内容都是jinja2的渲染语法,这个不是Web框架需要做的事,最终,居然在Werkzeug的官方文档里找到模板渲染的代码. ...
- T4文本模板
<#...#> 可以包含语句 <#=...#> 用于表达式,提供“输出”操作 <#+ ...> 使用类功能控制块向文本模板添加方法.属性.字段,必须作为文件中最后 ...
- 一个简单的Android富文本TextView实现
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Helvetica; color: #555555 } p.p2 { margin: 0.0p ...
- 一个简单的Dump转文本工具—Dump2Text
每次电脑重装都得烦心,要把庞大的IDE重新配置一次,正准备安装Visual Stdio 2010,上网找镜像的时候发现,Visual Stdio 2013推出了Community版,不仅没有lite掉 ...
- MVC开发T4代码生成之一----文本模板基础
T4文本模板 T4全写为Text Template Transformation Toolkit,是一种编程辅助工具,用来使程序代码自(懒)动(猿)生(福)成(利)的工具.MVC开发中大量使用了T4模 ...
随机推荐
- ASP.NET绑定学习
1.直接绑定到页面成员<asp:Repeater ... DataSource='<%#页面方法或属性%>'></asp:Repeater> 2.绑定到数组< ...
- 教你轻松计算AOE网关键路径
认识AOE网 有向图中,用顶点表示活动,用有向边表示活动之间开始的先后顺序,则称这种有向图为AOV网络:AOV网络可以反应任务完成的先后顺序(拓扑排序). 在AOV网的边上加上权值表示完成该活动所需的 ...
- Java中监控文件变化的多种方案
一.使用Apache.Common.io库 package yungoal.huafeng.utils.files; import com.sun.deploy.util.SyncFileAccess ...
- Visual SVN的安装
作为一个程序开发人员,就算自己一个人写程序,也应该有一个SVN版本控制系统,以便对开发代码进行有效的管理.今天我就介绍一个在Windows环境下简单快速搭建SVN服务器的方法. 通常的SVN服务器是搭 ...
- JMX入门开发
什么是JMX?或者是JMX是做什么的?我的理解是:可以远程管理/编辑JAVA对象.如图: 上面的SchemaName属性就是可以动态修改的,那么是如何做到的哪?下面咱们逐步分析. 一.首先假设咱们有个 ...
- Linux文件权限与目录
1:文件操作者的身份 owner:创建文件.拥有文件的登录用户. group:同一群组内的用户. others:其他登录用户. [系统账户与密码信息保存在/etc/passwd:个人账户与密码信息保存 ...
- Artistic Style在windows下的使用(C/C++)
ArtisticStyle是一个开源的源码格式化工具.主页地址为:http://astyle.sourceforge.net/,它能够应用在C.C++.Objective-C.C#.Java等程序语言 ...
- redis数据淘汰策略
概述 在 redis 中,允许用户设置最大使用内存大小 server.maxmemory,在内存限定的情况下是很有用的.譬如,在一台 8G 机子上部署了 4 个 redis 服务点,每一个服务点分配 ...
- 无限极分类php实现—查子孙树、家谱树
1.本文更新日期:2018/05/20 , 亲测可用,在原有基础上进行增强和 详细化 . 2.面包屑导航 和 子孙树 效果图如下: 3.代码: <?php // 无限级分类中,查家谱树(面包屑导 ...
- node下使用jquery
node使用jquery的两种方式 在node下,使用jquery有两种方法: 使用jsdom模拟一个window对象 使用cheerio,cheerio只实现了jquery的dom部分功能,相当于j ...