一个简单的代码生成器(T4文本模板运用)
2014-06-29 18:59
274 查看
说要写这篇文章有一段时间了,但因为最近各方面的压力导致心情十二分的不好,下班后往往都洗洗睡了。今天痛定思痛,终于把这件拖了很久的事做了。好,不废话了,现在看看"一个简单的代码生成器".
简约到如此,说是代码生成器,估计是要被吐槽的。好吧,借用园子里博友的说法,这只是一粒粟子,如果你愿意,你能看到代码生成器的“种子”。
画了个简图已描述这个简单的代码生成器的工作过程。下面的介绍将以此图展开:
1)读取数据表的信息:从数据库中读取数据表的信息并转换成要为T4文本模板引擎提供的数据(EntityClassInfo);
2)将要为T4文本模板引擎提供的数据(EntityClassInfo)作为参数传递给T4文本模板引擎(其实是T4文本模板引擎的宿主,详见T4文本模板转换过程);
3)T4文本模板引擎读取模板;
4)T4文本模板引擎将生成的文本返回给应用程序。
备注:
源码下载(VS2010项目):一个简单的代码生成器(T4文本模板运用)
先看看界面吧!
简约到如此,说是代码生成器,估计是要被吐槽的。好吧,借用园子里博友的说法,这只是一粒粟子,如果你愿意,你能看到代码生成器的“种子”。
这样运行的!
画了个简图已描述这个简单的代码生成器的工作过程。下面的介绍将以此图展开:
1)读取数据表的信息:从数据库中读取数据表的信息并转换成要为T4文本模板引擎提供的数据(EntityClassInfo);
2)将要为T4文本模板引擎提供的数据(EntityClassInfo)作为参数传递给T4文本模板引擎(其实是T4文本模板引擎的宿主,详见
3)T4文本模板引擎读取模板;
4)T4文本模板引擎将生成的文本返回给应用程序。
代码:
一、在应用程序和代码中传递的参数的类型
1)EntityClassInfo.cs
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Data;
namespaceEntityInfo
{
[Serializable]
publicclassEntityClassInfo
{
publicEntityClassInfo(DataTabledt)
{
this.ClassName=dt.TableName;
List<EntityClassPropertyInfo>ropertyListTemp=newList<EntityClassPropertyInfo>();
foreach(DataColumndcolindt.Columns)
{
ropertyListTemp.Add(newEntityClassPropertyInfo(dcol));
}
this.RopertyList=ropertyListTemp;
List<EntityClassPropertyInfo>primaryKeyListTemp=newList<EntityClassPropertyInfo>();
List<EntityClassPropertyInfo>notPrimaryKeyListTemp=newList<EntityClassPropertyInfo>(ropertyListTemp);
foreach(DataColumndcolindt.PrimaryKey)
{
primaryKeyListTemp.Add(newEntityClassPropertyInfo(dcol));
notPrimaryKeyListTemp.Remove(newEntityClassPropertyInfo(dcol));
}
this.PrimaryKeyList=primaryKeyListTemp;
this.NotPrimaryKeyList=notPrimaryKeyListTemp;
}
publicstringClassName
{
get;
privateset;
}
publicList<EntityClassPropertyInfo>RopertyList
{
get;
privateset;
}
publicList<EntityClassPropertyInfo>PrimaryKeyList
{
get;
privateset;
}
publicList<EntityClassPropertyInfo>NotPrimaryKeyList
{
get;
privateset;
}
}
}
2)EntityClassPropertyInfo.cs
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Data;
namespaceEntityInfo
{
[Serializable]
publicclassEntityClassPropertyInfo
{
publicEntityClassPropertyInfo(DataColumndcol)
{
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;
}
}
}
publicstringPropertyName
{
get;
privateset;
}
publicstringPropertyType
{
get;
privateset;
}
publicboolIsValueType
{
get;
privateset;
}
publicoverrideboolEquals(objectobj)
{
EntityClassPropertyInfotemp=objasEntityClassPropertyInfo;
if(this.PropertyName==temp.PropertyName&&this.PropertyType==temp.PropertyType)
{
returntrue;
}
returnfalse;
}
}
}
二、模板
1)生成实体类的模板:Entity.tt
<#@templatedebug="false"hostspecific="false"language="C#"#>
<#@outputextension=".txt"#>
<#@importnamespace="EntityInfo"#>
<#@parametertype="EntityInfo.EntityClassInfo"name="entity"#>
usingSystem;
usingSystem.Data;
usingSystem.Configuration;
usingSystem.Web;
usingSystem.Web.Security;
usingSystem.Web.UI;
usingSystem.Web.UI.WebControls;
usingSystem.Web.UI.WebControls.WebParts;
usingSystem.Web.UI.HtmlControls;
///<summary>
///<#=entity.ClassName#>的摘要说明
///</summary>
publicclass<#=entity.ClassName#>
{
public<#=entity.ClassName#>()
{
//
//TODO:在此处添加构造函数逻辑
//
}
<#foreach(EntityClassPropertyInfopropertyinentity.RopertyList)
{#>
private<#=property.PropertyType#>m_<#=property.PropertyName#>;
<#;
}
#>
<#foreach(EntityClassPropertyInfopropertyinentity.RopertyList)
{#>
public<#=property.PropertyType#><#=property.PropertyName#>
{
set{m_<#=property.PropertyName#>=value;}
get{returnm_<#=property.PropertyName#>;}
}
<#;
}
#>
}
2)生成DAL层的模板:DataAccess.tt
<#@templatedebug="false"hostspecific="false"language="C#"#>
<#@outputextension=".txt"#>
<#@importnamespace="EntityInfo"#>
<#@importnamespace="System.Collections.Generic"#>
<#@parametertype="EntityInfo.EntityClassInfo"name="entity"#>
usingSystem;
usingSystem.Data;
usingSystem.Configuration;
usingSystem.Web;
usingSystem.Web.Security;
usingSystem.Web.UI;
usingSystem.Web.UI.WebControls;
usingSystem.Web.UI.WebControls.WebParts;
usingSystem.Web.UI.HtmlControls;
usingMySql.Data.MySqlClient;
usingSystem.Collections.Generic;
///<summary>
///<#=entity.ClassName#>的摘要说明
///</summary>
publicclass<#=entity.ClassName#>DAL
{
public<#=entity.ClassName#>DAL()
{
}
#region私有方法
#region根据实体类获取MySqlParameter数组+MySqlParameter[]FromModel(<#=entity.ClassName#>model)
privatestaticMySqlParameter[]FromModel(<#=entity.ClassName#>model)
{
List<MySqlParameter>parameterList=newList<MySqlParameter>();
<#foreach(EntityClassPropertyInfopropertyinentity.RopertyList)
{
#>parameterList.Add(newMySqlParameter("@<#=property.PropertyName#>",SQLHelper.ToDBValue(model.<#=property.PropertyName#>)));
<#;
}
#>
returnparameterList.ToArray();
}
#endregion
#region将dr中的数据转换为实体类对象+<#=entity.ClassName#>ToModel(DataRowdr)
privatestatic<#=entity.ClassName#>ToModel(DataRowdr)
{
<#=entity.ClassName#>model=new<#=entity.ClassName#>();
<#foreach(EntityClassPropertyInfopropertyinentity.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#>;
<#;
}
}
#>
returnmodel;
}
#endregion
#endregion
#region增+intInsert(<#=entity.ClassName#>model)
publicstaticintInsert(<#=entity.ClassName#>model)
{
intresult=-1;
stringsql=@"INSERTINTO<#=entity.ClassName#>(<#=string.Join(",",GetSqlInsertInto())#>)
VALUES(<#=string.Join(",",GetSqlInsertValue())#>);";
result=SQLHelper.ExecuteNonQuery(sql,FromModel(model));
returnresult;
}
#endregion
#region删+intDeleteById(<#=string.Join(",",GetSqlDelVariable())#>)
publicstaticintDeleteById(<#=string.Join(",",GetSqlDelVariable())#>)
{
intresult=-1;
stringsql=@"DELETEFROM<#=entity.ClassName#>WHERE<#=string.Join("AND",GetSqlWhereId())#>;";
result=SQLHelper.ExecuteNonQuery(sql,<#=string.Join(",",GetSqlDelParameter())#>);
returnresult;
}
#endregion
#region改+intUpdate(<#=entity.ClassName#>model)
publicstaticintUpdate(<#=entity.ClassName#>model)
{
intresult=-1;
stringsql=@"UPDATE<#=entity.ClassName#>
SET<#=string.Join(",",GetSqlUpdateSet())#>
WHERE<#=string.Join("AND",GetSqlWhereId())#>";
result=SQLHelper.ExecuteNonQuery(sql,FromModel(model));
returnresult;
}
#endregion
#region查+intGetCountAll()
publicstaticintGetCountAll()
{
intresult=0;
stringsql=@"SELECTCount(*)FROM<#=entity.ClassName#>;";
result=Convert.ToInt32(SQLHelper.ExecuteScalar(sql));
returnresult;
}
#endregion
#region查+List<<#=entity.ClassName#>>GetBySql(stringsql,paramsMySqlParameter[]parameters)
publicstaticList<<#=entity.ClassName#>>GetBySql(stringsql,paramsMySqlParameter[]parameters)
{
List<<#=entity.ClassName#>>modelList=newList<<#=entity.ClassName#>>();
DataTabledt=SQLHelper.ExecuteDataTable(sql,parameters);
foreach(DataRowdrindt.Rows)
{
modelList.Add(ToModel(dr));
}
returnmodelList;
}
#endregion
}
<#+
privatestring[]GetSqlInsertInto()
{
List<string>propertyNameList=newList<string>();
foreach(EntityClassPropertyInfopropertyinentity.RopertyList)
{
propertyNameList.Add(property.PropertyName);
}
returnpropertyNameList.ToArray();
}
privatestring[]GetSqlInsertValue()
{
List<string>propertyNameList=newList<string>();
foreach(EntityClassPropertyInfopropertyinentity.RopertyList)
{
propertyNameList.Add("@"+property.PropertyName);
}
returnpropertyNameList.ToArray();
}
privatestring[]GetSqlDelVariable()
{
List<string>propertyList=newList<string>();
foreach(EntityClassPropertyInfopropertyinentity.PrimaryKeyList)
{
propertyList.Add(property.PropertyType+"m_"+property.PropertyName);
}
returnpropertyList.ToArray();
}
privatestring[]GetSqlDelParameter()
{
List<string>propertyList=newList<string>();
foreach(EntityClassPropertyInfopropertyinentity.PrimaryKeyList)
{
propertyList.Add("newMySqlParameter(@\""+property.PropertyName+"\",m_"+property.PropertyName+")");
}
returnpropertyList.ToArray();
}
privatestring[]GetSqlUpdateSet()
{
List<string>propertyList=newList<string>();
foreach(EntityClassPropertyInfopropertyinentity.NotPrimaryKeyList)
{
propertyList.Add(property.PropertyName+"=@"+property.PropertyName);
}
returnpropertyList.ToArray();
}
privatestring[]GetSqlWhereId()
{
List<string>propertyList=newList<string>();
foreach(EntityClassPropertyInfopropertyinentity.PrimaryKeyList)
{
propertyList.Add(property.PropertyName+"=@"+property.PropertyName);
}
returnpropertyList.ToArray();
}
#>
三、代码生成四步走:
1)从数据表信息=》EntityClassInfo:
DataTabledt=SQLHelper.ExecuteDataTable(SQLHelper.GetConnectionString(),string.Format("SELECT*FROM{0}LIMIT0,0",cbbTableName.SelectedValue.ToString()));
EntityClassInfoentityInfo=newEntityClassInfo(dt);
备注:
#regionExecuteTable方法
publicstaticDataTableExecuteDataTable(stringconnectionString,stringsql,paramsMySqlParameter[]parameters)
{
using(MySqlConnectionconn=newMySqlConnection(connectionString))
{
using(MySqlCommandcmd=conn.CreateCommand())
{
cmd.CommandText=sql;
cmd.Parameters.AddRange(parameters);
using(MySqlDataAdapterda=newMySqlDataAdapter(cmd))
{
using(DataTabledt=newDataTable())
{
da.Fill(dt);
da.FillSchema(dt,SchemaType.Source);//从数据源中检索架构
returndt;
}
}
}
}
}
#endregion
2)给T4文本模板传参:
CustomTextTemplatingEngineHosthost=newCustomTextTemplatingEngineHost();
host.Session=newTextTemplatingSession();
host.Session.Add("entity",classInfo);
3)读取文本模板:
stringinput=File.ReadAllText(templatePath);
stringoutput=newEngine().ProcessTemplate(input,host);
4)返回生成的文本:
stringoutput=newEngine().ProcessTemplate(input,host);
源码下载(VS2010项目):
相关文章推荐
- T4模板——一个神奇的代码生成器
- 用T4模板实现简单的代码生成器
- 用Windows API实现一个简单的文本输入框(上)
- 默默简单的写了一个模板引擎
- 一个LaTeX/CJK中文文档的简单而实用的模板
- 一个简单文本操作
- 我做的一个java简单文本编辑器代码
- 一个简单的通用回调模板
- 基于WinCE的一个简单的流程序驱动模板
- 2. 一个简单的Servlet--产生存文本下面是一个产生存文本的简单servlet的实例
- 用Windows API实现一个简单的文本输入框(下)
- php初探: 一个简单的mysql数据库分页的程序模板
- 一个简单的ibatis.net架构(包含项目模板代码下载)
- 利用page rank,hits算法实现的一个简单的文本摘要系统
- 自己写的一个简单文本批量编辑器, 附源码
- 一个简单的模板系统的实现(动态载入DLL)
- 一个简单的wince.net流驱动模板
- 蛙蛙推荐:用脚本写一个支持模板的代码生成器
- OpenCms JSP 模板开发——创建一个简单的JSP模板
- C#简单文本编辑器(利用ToolStrip、enu、一个事件多个监听等)