T4 (Text Template Transformation Toolkit) 是一个基于模板的代码生成器。使用T4你可以通过写一些ASP.NET-like模板,来生成C#, T-SQL, XML等代码。
一 “Hello World ”代码生成器
1 创建一个C# Console工程,添加一个名为“HelloWorld.tt”的文本文件,将<#@ output extension=".cs" #>设为".cs"便会生成cs文件。
2 向HelloWorld.tt中添加以下内容
<#@ template language="C#" #>
// <autogenerated>
// This code was generated by a tool. Any changes made manually will be lost
// the next time this code is regenerated.
// </autogenerated>
usingSystem;
public class<#= this.ClassName #>
{
public static voidHelloPot()
{
Console.WriteLine("Hello World");
}
}
上面的模板将生成一个名为“HelloWorld”的类,当你保存HelloWorld.tt时,Visual Studio将为你生成以下代码:
// <autogenerated> // This code was generated by a tool. Any changes made manually will be lost // the next time this code is regenerated. // </autogenerated> using System; public class HelloWorld { public static void HelloPot() { Console.WriteLine("Hello World"); } }
3 添加另一个文本文件HelloWorld1.tt.,加入以下内容:
<#
this.ClassName = "HelloWorld1";
#>
<#@ include file="HelloT4.tt" #>
通过修改ClassName的值可以更改类名,以上模板将生成一个名为HelloWorld1类。
// <autogenerated> // This code was generated by a tool. Any changes made manually will be lost // the next time this code is regenerated. // </autogenerated> using System; public class HelloWorld1 { public static void HelloPot() { Console.WriteLine("Hello World"); } }
二 数据库自动生成实体类
这个实例会创建一个模板为数据库中的每一张表,自动创建相应的实体类。
1 首先我们需要添加一些程序集引用,命名空间。
<#@ template language="C#" debug="True" hostspecific="True" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.xml" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Data" #>
2 获取数据库表结构.
<#
stringconnectionString = "data source=.""SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=MIAPortal;";
SqlConnection conn = newSqlConnection(connectionString);
conn.Open();
System.Data.DataTable schema = conn.GetSchema("TABLES");
stringselectQuery = "select * from @tableName";
SqlCommand command = newSqlCommand(selectQuery,conn);
SqlDataAdapter ad = newSqlDataAdapter(command);
System.Data.DataSet ds = newDataSet();
我们通过GetSchema("TABLES")获取了数据库中所有表的表名,接着通过表名,获取相应表的表结构。
3 生成代码如下
<#@ template language="C#" debug="True" hostspecific="True" #> <#@ output extension=".cs" #> <#@ assembly name="System.Data" #> <#@ assembly name="System.xml" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Data.SqlClient" #> <#@ import namespace="System.Data" #> using System; namespace MyProject.Entities { <# string connectionString = "data source=.""SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=MIAPortal;"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); System.Data.DataTable schema = conn.GetSchema("TABLES"); string selectQuery = "select * from @tableName"; SqlCommand command = new SqlCommand(selectQuery,conn); SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { <# ds.Tables.Clear(); command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); foreach (DataColumn dc in ds.Tables[0].Columns) { #> private <#= dc.DataType.Name #> _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set { _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> = value; } } <# } #> } <# } #> }