标签:t4 text template transformation toolkit
在开发过程种,很多时候我们会写很多相似度很高的代码,书写这些代码是有规律的,比如我们会根据数据表生成实体类,就像EF那样,会从表中自动生成实体类,如果我们写一个应用程序,读取数据库,然后生成一个.cs类文件,这个相对简单,如果在VS中能解决这个问题,不用单跑一个执行程序就happy了,那T4就是来干这件事的。T4是Text Template Transformation Toolkit全称,不作更多的解释,VS中的T4详见https://msdn.microsoft.com/zh-cn/library/bb126445.aspx。
简单看一个例子,就是把数据的表生成对应的实体类,在项目中创建一个“运行时文本模版”,扩展名是.tt,其实.tt中的代码是标准的C#代码,并键时.tt可以在设计时生成.cs文件,也可以运行时生成,本例是设计时生成,代码如下:
<#@ template debug="false" hostspecific="true" language="C#" #><#@ assembly name="System.Core" #><#@ assembly name="System.Data" #><#@ assembly name="System.Configuration" #><#@ assembly name="System.Xml" #><#@ import namespace="System.Linq" #><#@ import namespace="System.Text" #><#@ import namespace="System.Collections.Generic" #><#@ import namespace="System.Data" #><#@ import namespace="System.Data.SqlClient" #><#@ import namespace="System.Configuration" #><#@ import namespace="System.Xml" #><#@ output extension=".txt" #>
<#//数据库连接字符串
var constr="server=.;database=testdb;uid=sa;pwd=gsw123;";
//遍历实体类并生成
foreach (var clas in BuildClass(constr))
{
WriteFile(clas.Key,BuildContent(clas.Value));
AddFileToProject(clas.Key);
}#>生成实体类成功!
<#+
//组装实体类和它的命名空间
string BuildContent(string content)
{
return @"
/*****************************
*作者:桂素伟
*时间:"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+@"
*说明:按照数据库表自动生成的类
******************************/
using System;
using System.Text;
namespace "+Host.ResolveAssemblyReference("$(ProjectName)")+@"
{
"+
content
+@"
}
";
}
//把生成的实体类文件添加到当前项目中
public void AddFileToProject(string className)
{
//获取当前项目的名称
var proName=Host.ResolveAssemblyReference("$(ProjectName)")+".csproj";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(System.IO.File.ReadAllText(Host.ResolveAssemblyReference("$(ProjectDir)")+@"\"+proName,Encoding.Default));
XmlNode root = xmlDoc.DocumentElement;
if( !root.InnerXml.Contains(@"Include=""" + className + @".cs"""))
{
root.InnerXml += @"<ItemGroup><Compile Include="""+className+@".cs""></Compile></ItemGroup>";
xmlDoc.Save(Host.ResolveAssemblyReference("$(ProjectDir)")+@"\"+proName);
}
}
//生成实体类文件
public void WriteFile(string className,string content)
{
var writer = new System.IO.StreamWriter(Host.ResolveAssemblyReference("$(ProjectDir)")+@"\"+className + ".cs", false, Encoding.Default);
writer.Write(content);
writer.Flush();
writer.Close();
}
//从数据库获取实体类名和实体类源码
public Dictionary<string,string> BuildClass(string constr)
{
using (var con = new System.Data.SqlClient.SqlConnection(constr))
{
var cmd = new System.Data.SqlClient.SqlCommand();
cmd.CommandText = "select name from sys.tables WHERE name!=‘sysdiagrams‘ AND name!=‘__MigrationHistory‘";
cmd.Connection = con;
con.Open();
var dr = cmd.ExecuteReader();
var dt = new DataTable();
dt.Load(dr);
dr.Close();
var dic =new Dictionary<string, string>();
foreach (DataRow row in dt.Rows)
{
cmd.CommandText = string.Format(@"select COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,IS_NULLABLE
from information_schema.columns WHERE TABLE_NAME = ‘{0}‘", row["name"].ToString());
var fielddr = cmd.ExecuteReader();
var fieldTable = new DataTable();
fieldTable.Load(fielddr);
fielddr.Close();
dic.Add(row["name"].ToString(), CreateClass(row["name"].ToString(), fieldTable));
}
return dic;
}
}
public string CreateClass(string className, DataTable fields)
{
var csBuilder = new StringBuilder("\r\n");
csBuilder.AppendLine(string.Format(@" public class {0}", className));
csBuilder.AppendLine(@" {");
foreach (DataRow row in fields.Rows)
{
csBuilder.AppendLine(CreateProperty(row));
}
csBuilder.AppendLine(@" }");
return csBuilder.ToString();
}
//生成属性
public string CreateProperty(DataRow row)
{
var dic = new Dictionary<string, string>();
dic.Add("nvarchar", "string");
dic.Add("varchar", "string");
dic.Add("char", "string");
dic.Add("text", "string");
dic.Add("int", "string");
dic.Add("money", "decimal");
dic.Add("float", "float");
dic.Add("bit", "bool");
var csBuilder = new StringBuilder();
csBuilder.AppendLine(string.Format(@" public {0} {1}", dic[row["DATA_TYPE"].ToString().ToLower()], row["COLUMN_NAME"].ToString()));
csBuilder.AppendLine(@" {");
csBuilder.AppendLine(string.Format(@" get;"));
csBuilder.AppendLine(string.Format(@" set;"));
csBuilder.AppendLine(@" }");
return csBuilder.ToString();
}
#>本文出自 “桂素伟” 博客,请务必保留此出处http://axzxs.blog.51cto.com/730810/1774815
标签:t4 text template transformation toolkit
原文地址:http://axzxs.blog.51cto.com/730810/1774815