T4的語法與asp.net的方式比較類似。主要包括指令、文本塊、控制塊。
1.1 指令
指令主要包括template, output, assembly, import, include等類型,用以告訴T4引擎如何編譯和運行一個模板。這些指令相當于T4引擎的配置參數。
示例:
<#@ template debug="true" hostspecific="true" language="C#" #>
告訴T4引擎控制塊用c#編寫;
<#@ output extension=".cs" #>
告訴T4引擎生成文件的后綴名是.cs;
<#@ assembly name="System.Core"#>
告訴T4引擎編譯運行時引用System.Core程序集;
<#@ assembly name="$(SolutionDir)/PRoject.CodeGenerator/bin/Debug/MySQL.Data.Dll" #>
告訴T4引擎引用一個特定的位置上的程序集;
<#@ import namespace="System.Data.SqlClient"#>
告訴T4引擎編譯運行時引用某個名稱空間
<#@ include file="../Code/DBSchema.ttinclude"#>
告訴T4引擎編譯運行時引用某個文件,類似于JS的引用
1.2 文本塊
文本塊, T4引擎會將文本塊的內容直接復制到輸出文件中。
1.3 控制塊
控制塊,主要用于控制文本的輸出。在控制塊可以寫任意的C#代碼。
1.4 示例Hello world
<#@ template debug="true" hostspecific="true" language="C#" #><#@ output extension=".txt" #>Hello, <#Write("World");#>轉載自:http://www.olegsych.com/2007/12/text-template-transformation-toolkit/

1> Step1:編譯模板,根據指令編譯模板中的文本塊和控制塊,并生成一個繼承于TextTransformation的類。
2> Step2: T4引擎動態創建類的實例,并調用TransformText方法。
我們用T4時,主要是基于數據庫或配置文件來生成各類的代碼。所以如何有效地獲取數據庫的結構信息,是比較重要的。 之前看很多人直接把獲取數據庫的信息放在每一個模板中,在更換其它數據庫時,又要重寫模板。一個模板同時支持多個項目時,不同的項目數據庫很有可能是不同的。
主要設計思想如下,簡單地應用了簡單工廠模式。通過DBSchemaFactory類根據不同數據庫類型,獲取數據庫訪問類的接口IDBSchema。最后返回相同的表結構信息。

DBSchema.ttinclude類:
根據不同的數據庫,獲取表結構信息。已包括SQLSERVER和MYSQL。

<#@ assembly name="System.Core"#><#@ assembly name="System.Data" #><#@ assembly name="System.xml" #><#@ assembly name="$(SolutionDir)/bin/Debug/MySql.Data.Dll" #><#@ import namespace="System"#><#@ import namespace="System.Collections.Generic"#><#@ import namespace="System.Data"#><#@ import namespace="System.Data.SqlClient"#><#@ import namespace="MySql.Data.MySqlClient"#><#+ #region Code public class DBSchemaFactory { static readonly string DatabaseType = "SqlServer"; public static IDBSchema GetDBSchema() { IDBSchema dbSchema; switch (DatabaseType) { case "SqlServer": { dbSchema =new SqlServerSchema(); break; } case "MySql": { dbSchema = new MySqlSchema(); break; } default: { throw new ArgumentException("The input argument of DatabaseType is invalid!"); } } return dbSchema; } } public interface IDBSchema : IDisposable { List<string> GetTablesList(); Table GetTableMetadata(string tableName); } public class SqlServerSchema : IDBSchema { public string ConnectionString = "Data Source=.;Initial Catalog=ProjectData;Persist Security Info=True;User ID=sa;PassWord=123456;"; public SqlConnection conn; public SqlServerSchema() { conn = new SqlConnection(ConnectionString); conn.Open(); } public List<string> GetTablesList() { DataTable dt = conn.GetSchema("Tables"); List<string> list = new List<string>(); foreach (DataRow row in dt.Rows) { list.Add(row["TABLE_NAME"].ToString()); } return list; } public Table GetTableMetadata(string tableName) { string selectCmdText = string.Format("SELECT * FROM {0}", tableName); ; SqlCommand command = new SqlCommand(selectCmdText, conn); SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); ad.FillSchema(ds, SchemaType.Mapped, tableName); Table table = new Table(ds.Tables[0]); return table; } public void Dispose() { if (conn != null) conn.Close(); } } public class MySqlSchema : IDBSchema { public string ConnectionString = "Server=localhost;Port=3306;Database=ProjectData;Uid=root;Pwd=;"; public MySqlConnection conn; public MySqlSchema() { conn = new MySqlConnection(ConnectionString); conn.Open(); } public List<string> GetTablesList() { DataTable dt = conn.GetSchema("Tables"); List<string> list = new List<string>(); foreach (DataRow row in dt.Rows) { list.Add(row["TABLE_NAME"].ToString()); } return list; } public Table GetTableMetadata(string tableName) { string selectCmdText = string.Format("SELECT * FROM {0}", tableName); ; MySqlCommand command = new MySqlCommand(selectCmdText, conn); MySqlDataAdapter ad = new MySqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); ad.FillSchema(ds, SchemaType.Mapped, tableName); Table table = new Table(ds.Tables[0]); return table; } public void Dispose() { if (conn != null) conn.Close(); } } public class Table { public Table(DataTable t) { this.PKs = this.GetPKList(t); this.Columns = this.GetColumnList(t); this.ColumnTypeNames = this.SetColumnNames(); } public List<Column> PKs; public List<Column> Columns; public string ColumnTypeNames; public List<Column> GetPKList(DataTable dt) { List<Column> list = new List<Column>(); Column c = null; if (dt.PrimaryKey.Length > 0) { list = new List<Column>(); foreach (DataColumn dc in dt.PrimaryKey) { c = new Column(dc); list.Add(c); } } return list; } private List<Column> GetColumnList(DataTable dt) { List<Column> list = new List<Column>(); Column c = null; foreach (DataColumn dc in dt.Columns) { c = new Column(dc); list.Add(c); } return list; } private string SetColumnNames() { List<string> list = new List<string>(); foreach (Column c in this.Columns) { list.Add(string.Format("{0} {1}", c.TypeName, c.LowerColumnName)); } return string.Join(",", list.ToArray()); } } public class Column { DataColumn columnBase; public Column(DataColumn columnBase) { this.columnBase = columnBase; } public string ColumnName { get { return this.columnBase.ColumnName; } } public string MaxLength { get { return this.columnBase.MaxLength.ToString(); } } public string TypeName { get { string result = string.Empty
新聞熱點
疑難解答