博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个简单的代码生成器(T4文本模板运用)
阅读量:6616 次
发布时间:2019-06-24

本文共 9989 字,大约阅读时间需要 33 分钟。

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


先看看界面吧!

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

这样运行的!

画了个简图已描述这个简单的代码生成器的工作过程。下面的介绍将以此图展开:

1)读取数据表的信息:从数据库中读取数据表的信息并转换成要为T4文本模板引擎提供的数据(EntityClassInfo);

2)将要为T4文本模板引擎提供的数据(EntityClassInfo)作为参数传递给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
ropertyListTemp = new List
();
 
foreach (DataColumn dcol in dt.Columns)
{
ropertyListTemp.Add(new EntityClassPropertyInfo(dcol));
}
this.RopertyList = ropertyListTemp;
 
List
primaryKeyListTemp = new List
();
List
notPrimaryKeyListTemp = new List
(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
RopertyList
{
get;
private set;
}
public List
PrimaryKeyList
{
get;
private set;
}
public List
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;
 
/// 
/// <#= entity.ClassName#> 的摘要说明
/// 
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;
 
/// 
/// <#= entity.ClassName#> 的摘要说明
/// 
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
parameterList = new List
();
<#  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
propertyNameList= new List
();
foreach(EntityClassPropertyInfo property in entity.RopertyList)
{
propertyNameList.Add(property.PropertyName);
}
return propertyNameList.ToArray();
}
private string[] GetSqlInsertValue()
{
List
propertyNameList= new List
();
foreach(EntityClassPropertyInfo property in entity.RopertyList)
{
propertyNameList.Add("@" + property.PropertyName);
}
return propertyNameList.ToArray();
}
private string[] GetSqlDelVariable()
{
List
propertyList= new List
();
foreach(EntityClassPropertyInfo property in entity.PrimaryKeyList)
{
propertyList.Add(property.PropertyType + "  m_" + property.PropertyName);
}
return propertyList.ToArray();
}
private string[] GetSqlDelParameter()
{
List
propertyList= new List
();
foreach(EntityClassPropertyInfo property in entity.PrimaryKeyList)
{
propertyList.Add("new MySqlParameter(@\"" + property.PropertyName + "\" ,m_" + property.PropertyName + ")");
}
return propertyList.ToArray();
}
 
private string[] GetSqlUpdateSet()
{
List
propertyList= new List
();
foreach(EntityClassPropertyInfo property in entity.NotPrimaryKeyList)
{
propertyList.Add(property.PropertyName +"=@" + property.PropertyName);
}
return propertyList.ToArray();
}
private string[] GetSqlWhereId()
{
List
propertyList= new List
();
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项目):

转载地址:http://umhso.baihongyu.com/

你可能感兴趣的文章
云计算:大势所趋 你准备好了么?
查看>>
数据资产的运营商--天市大数据交易平台
查看>>
中小企业如何成功转型跨境电商
查看>>
java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**
查看>>
《ANTLR 4权威指南》——2.5 语法分析树监听器和访问器
查看>>
02_JNI中Java代码调用C代码,Android中使用log库打印日志,javah命令的使用,Android.mk文件的编写,交叉编译...
查看>>
TIOBE 2016 年 5 月编程语言排行榜:Ruby 排名创历史新高
查看>>
这些国货,在阿里平台上被美国剁手党抢疯了
查看>>
《Excel 职场手册:260招菜鸟变达人》一第 2 招 常用快捷键Windows与Mac对照
查看>>
《Greenplum企业应用实战》一第1章 Greenplum简介1.1 Greenplum的起源和发展历程
查看>>
开源世界已成围城:成本让企业蜂拥而来,也让企业退缩转投
查看>>
嵌入式实时应用开发实战(原书第3版)》——3.3 保护模式架构
查看>>
《Python编程快速上手——让繁琐工作自动化》——1.4 在变量中保存值
查看>>
Git 两分钟指南
查看>>
想改进你的卷积神经网络?看看这14种设计模式!
查看>>
安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情(六)
查看>>
[LeetCode]--100. Same Tree
查看>>
阿里蒋晓伟谈流计算和批处理引擎Blink,以及Flink和Spark的异同与优势
查看>>
快速掌握Redis——第二招:安装
查看>>
从Jetty、Tomcat和Mina中提炼NIO构架网络服务器的经典模式(一)
查看>>