1   T4语法

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");#>

 

2   工作原理

转载自:http://www.olegsych.com/2007/12/text-template-transformation-toolkit/

用T4 Template生成代码

1>     Step1:编译模板,根据指令编译模板中的文本块和控制块,并生成一个继承于TextTransformation的类。

2>     Step2: T4引擎动态创建类的实例,并调用TransformText方法。

3  在T4中读取表结构

我们用T4时,主要是基于数据库或配置文件来生成各类的代码。所以如何有效地获取数据库的结构信息,是比较重要的。 之前看很多人直接把获取数据库的信息放在每一个模板中,在更换其它数据库时,又要重写模板。一个模板同时支持多个项目时,不同的项目数据库很有可能是不同的。

主要设计思想如下,简单地应用了简单工厂模式。通过DBSchemaFactory类根据不同数据库类型,获取数据库访问类的接口IDBSchema。最后返回相同的表结构信息。

用T4 Template生成代码

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;
                if (this.columnBase.DataType.Name == "Guid")//for mysql,因为对于MYSQL如果是CHAR(36),类型自动为Guid
                    result = "String";
                else
                    result = this.columnBase.DataType.Name;
                return result; 
            } 
        }

        public bool AllowDBNull { get { return this.columnBase.AllowDBNull; } }

        public string UpColumnName
        {
            get
            {
                return string.Format("{0}{1}", this.ColumnName[0].ToString().ToUpper(), this.ColumnName.Substring(1));
            }
        }

        public string LowerColumnName
        {
            get
            {
                return string.Format("{0}{1}", this.ColumnName[0].ToString().ToLower(), this.ColumnName.Substring(1));
            }
        }
    }

    public class GeneratorHelper
    {
        public static readonly string StringType = "String";
        public static readonly string DateTimeType = "DateTime";
        public static string GetQuesMarkByType(string typeName)
        {
            string result = typeName;
            if (typeName == DateTimeType)
            {
                result += "?";
            }
            return result;
        }
    }

    #endregion
#>
View Code

相关文章:

  • 2022-01-09
  • 2021-07-16
  • 2021-08-20
  • 2021-04-09
  • 2022-01-07
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-06-04
  • 2021-12-13
  • 2021-09-05
  • 2021-11-20
  • 2022-02-24
相关资源
相似解决方案