您的位置:首页 > 编程语言

一个简单的代码生成器(T4文本模板运用)

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

先看看界面吧!





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

这样运行的!





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

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

2)将要为T4文本模板引擎提供的数据(EntityClassInfo)作为参数传递给T4文本模板引擎(其实是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文本模板运用)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: