1.什么是t4模版

T4,即4T开头的英文字母组合:Text Template Transformation Toolkit

T4(Text Template Transformation Toolkit)是微软官方在VisualStudio 2008中开始使用的代码生成引擎。在 Visual Studio 中,“T4 文本模板”是由一些文本块和控制逻辑组成的混合模板,它可以生成文本文件。 在 Visual C# 或 Visual Basic 中,控制逻辑编写为程序代码的片段。生成的文件可以是任何类型的文本,例如网页、资源文件或任何语言的程序源代码。现在的VS中只要与代码生成相关的场景基本上都能找T4的身影,比如MVC的视图模板,Entity Framwork的DataContext模板等等。

可以所T4模版课快速帮你生产实体类或者需要重复编写但是格式一致的代码

2.T4模版初试篇

首先看下运行效果:

我这手里有一个还没有编写实体类的项目,我们拿则个项目来测试下t4模版的强大之处

(1)首先我先新创建一个类库专门存放t4模版

(2)新创建一个 DbHelper.ttinclude 模板,主要是数据库操作类

<#+public class config{public static readonly string ConnectionString = "Server=.;Database=XXXX;User ID=sa;Password=你的数据库密码";public static readonly string DbDatabase = "";public static readonly string TableName = "";}
#>
<#+ public class DbHelper{#region GetDbTablespublic static List<string> GetDbTablesNew(string connectionString, string database,string tables = null){ if (!string.IsNullOrEmpty(tables)){tables = string.Format(" and obj.name in ('{0}')", tables.Replace(",", "','"));}string sql = string.Format(@"SELECTobj.name tablenamefrom {0}.sys.objects obj inner join {0}.dbo.sysindexes idx on obj.object_id=idx.id and idx.indid<=1INNER JOIN {0}.sys.schemas schem ON obj.schema_id=schem.schema_idleft join {0}.sys.extended_properties g ON (obj.object_id = g.major_id AND g.minor_id = 0 AND g.name= 'MS_Description')where type='U' {1} order by obj.name", database,tables);DataTable dt = GetDataTable(connectionString, sql);return dt.Rows.Cast<DataRow>().Select(row =>row.Field<string>("tablename")).ToList();}public static List<DbTable> GetDbTables(string connectionString, string database, string tables = null){if (!string.IsNullOrEmpty(tables)){tables = string.Format(" and obj.name in ('{0}')", tables.Replace(",", "','"));}#region SQLstring sql = string.Format(@"SELECTobj.name tablename,schem.name schemname,idx.rows,CAST(CASE WHEN (SELECT COUNT(1) FROM sys.indexes WHERE object_id= obj.OBJECT_ID AND is_primary_key=1) >=1 THEN 1ELSE 0END AS BIT) HasPrimaryKey                                         from {0}.sys.objects obj inner join {0}.dbo.sysindexes idx on obj.object_id=idx.id and idx.indid<=1INNER JOIN {0}.sys.schemas schem ON obj.schema_id=schem.schema_idwhere type='U' {1}order by obj.name", database, tables);#endregionDataTable dt = GetDataTable(connectionString, sql);return dt.Rows.Cast<DataRow>().Select(row => new DbTable{TableName = row.Field<string>("tablename"),SchemaName = row.Field<string>("schemname"),Rows = row.Field<int>("rows"),HasPrimaryKey = row.Field<bool>("HasPrimaryKey")}).ToList();}#endregion#region GetDbColumnspublic static List<DbColumn> GetDbColumns(string connectionString, string database, string tableName, string schema = "dbo"){#region SQLstring sql = string.Format(@"WITH indexCTE AS(SELECT ic.column_id,ic.index_column_id,ic.object_id    FROM {0}.sys.indexes idxINNER JOIN {0}.sys.index_columns ic ON idx.index_id = ic.index_id AND idx.object_id = ic.object_idWHERE  idx.object_id =OBJECT_ID(@tableName) AND idx.is_primary_key=1)selectcolm.column_id ColumnID,CAST(CASE WHEN indexCTE.column_id IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey,colm.name ColumnName,systype.name ColumnType,colm.is_identity IsIdentity,colm.is_nullable IsNullable,cast(colm.max_length as int) ByteLength,(case when systype.name='nvarchar' and colm.max_length>0 then colm.max_length/2 when systype.name='nchar' and colm.max_length>0 then colm.max_length/2when systype.name='ntext' and colm.max_length>0 then colm.max_length/2 else colm.max_lengthend) CharLength,cast(colm.precision as int) Precision,cast(colm.scale as int) Scale,prop.value Remarkfrom {0}.sys.columns colminner join {0}.sys.types systype on colm.system_type_id=systype.system_type_id and colm.user_type_id=systype.user_type_idleft join {0}.sys.extended_properties prop on colm.object_id=prop.major_id and colm.column_id=prop.minor_idLEFT JOIN indexCTE ON colm.column_id=indexCTE.column_id AND colm.object_id=indexCTE.object_id                                        where colm.object_id=OBJECT_ID(@tableName)order by colm.column_id", database);#endregionSqlParameter param = new SqlParameter("@tableName", SqlDbType.NVarChar, 100) { Value = string.Format("{0}.{1}.{2}", database, schema, tableName) };DataTable dt = GetDataTable(connectionString, sql, param);return dt.Rows.Cast<DataRow>().Select(row => new DbColumn(){ColumnID = row.Field<int>("ColumnID"),IsPrimaryKey = row.Field<bool>("IsPrimaryKey"),ColumnName = row.Field<string>("ColumnName"),ColumnType = row.Field<string>("ColumnType"),IsIdentity = row.Field<bool>("IsIdentity"),IsNullable = row.Field<bool>("IsNullable"),ByteLength = row.Field<int>("ByteLength"),CharLength = row.Field<int>("CharLength"),Precision=row.Field<int>("Precision"),Scale = row.Field<int>("Scale"),Remark = row["Remark"].ToString()}).ToList();}#endregion#region GetDataTablepublic static DataTable GetDataTable(string connectionString, string commandText, params SqlParameter[] parms){using (SqlConnection connection = new SqlConnection(connectionString)){SqlCommand command = connection.CreateCommand();command.CommandText = commandText;command.Parameters.AddRange(parms);SqlDataAdapter adapter = new SqlDataAdapter(command);DataTable dt = new DataTable();adapter.Fill(dt);return dt;}}#endregion#region GetPrimaryKeypublic static string GetPrimaryKey(List<DbColumn> dbColumns){string primaryKey = string.Empty;if (dbColumns!=null&&dbColumns.Count>0){foreach (var item in dbColumns){if (item.IsPrimaryKey==true){primaryKey = item.ColumnName;}}}return primaryKey;}#endregion}#region DbTablepublic sealed class DbTable{public string TableName { get; set; }public string SchemaName { get; set; }public int Rows { get; set; }public bool HasPrimaryKey { get; set; }}#endregion#region DbColumnpublic sealed class DbColumn{public int ColumnID { get; set; }public bool IsPrimaryKey { get; set; }public string ColumnName { get; set; }public string ColumnType { get; set; }public string CSharpType{get{return SqlServerDbTypeMap.MapCsharpType(ColumnType);}}/// <summary>/// /// </summary>public Type CommonType{get{return SqlServerDbTypeMap.MapCommonType(ColumnType);}}public int ByteLength { get; set; }public int CharLength { get; set; }public int Precision{get;set;}public int Scale { get; set; }public bool IsIdentity { get; set; }public bool IsNullable { get; set; }public string Remark { get; set; }}#endregion#region SqlServerDbTypeMappublic class SqlServerDbTypeMap{public static string MapCsharpType(string dbtype){if (string.IsNullOrEmpty(dbtype)) return dbtype;dbtype = dbtype.ToLower();string csharpType = "object";switch (dbtype){case "bigint": csharpType = "long"; break;case "binary": csharpType = "byte[]"; break;case "bit": csharpType = "bool"; break;case "char": csharpType = "string"; break;case "date": csharpType = "DateTime"; break;case "datetime": csharpType = "DateTime"; break;case "datetime2": csharpType = "DateTime"; break;case "datetimeoffset": csharpType = "DateTimeOffset"; break;case "decimal": csharpType = "decimal"; break;case "float": csharpType = "double"; break;case "image": csharpType = "byte[]"; break;case "int": csharpType = "int"; break;case "money": csharpType = "decimal"; break;case "nchar": csharpType = "string"; break;case "ntext": csharpType = "string"; break;case "numeric": csharpType = "decimal"; break;case "nvarchar": csharpType = "string"; break;case "real": csharpType = "Single"; break;case "smalldatetime": csharpType = "DateTime"; break;case "smallint": csharpType = "short"; break;case "smallmoney": csharpType = "decimal"; break;case "sql_variant": csharpType = "object"; break;case "sysname": csharpType = "object"; break;case "text": csharpType = "string"; break;case "time": csharpType = "TimeSpan"; break;case "timestamp": csharpType = "byte[]"; break;case "tinyint": csharpType = "byte"; break;case "uniqueidentifier": csharpType = "Guid"; break;case "varbinary": csharpType = "byte[]"; break;case "varchar": csharpType = "string"; break;case "xml": csharpType = "string"; break;default: csharpType = "object"; break;}return csharpType;}public static Type MapCommonType(string dbtype){if (string.IsNullOrEmpty(dbtype)) return Type.Missing.GetType();dbtype = dbtype.ToLower();Type commonType = typeof(object);switch (dbtype){case "bigint": commonType = typeof(long); break;case "binary": commonType = typeof(byte[]); break;case "bit": commonType = typeof(bool); break;case "char": commonType = typeof(string); break;case "date": commonType = typeof(DateTime); break;case "datetime": commonType = typeof(DateTime); break;case "datetime2": commonType = typeof(DateTime); break;case "datetimeoffset": commonType = typeof(DateTimeOffset); break;case "decimal": commonType = typeof(decimal); break;case "float": commonType = typeof(double); break;case "image": commonType = typeof(byte[]); break;case "int": commonType = typeof(int); break;case "money": commonType = typeof(decimal); break;case "nchar": commonType = typeof(string); break;case "ntext": commonType = typeof(string); break;case "numeric": commonType = typeof(decimal); break;case "nvarchar": commonType = typeof(string); break;case "real": commonType = typeof(Single); break;case "smalldatetime": commonType = typeof(DateTime); break;case "smallint": commonType = typeof(short); break;case "smallmoney": commonType = typeof(decimal); break;case "sql_variant": commonType = typeof(object); break;case "sysname": commonType = typeof(object); break;case "text": commonType = typeof(string); break;case "time": commonType = typeof(TimeSpan); break;case "timestamp": commonType = typeof(byte[]); break;case "tinyint": commonType = typeof(byte); break;case "uniqueidentifier": commonType = typeof(Guid); break;case "varbinary": commonType = typeof(byte[]); break;case "varchar": commonType = typeof(string); break;case "xml": commonType = typeof(string); break;default: commonType = typeof(object); break;}return commonType;}}#endregion#>

(3)再创建一个 ModelAuto.ttinclude 实体类生产模版

<#@ assembly name="System.Core"#>
<#@ assembly name="EnvDTE"#>
<#@ import namespace="System.Collections.Generic"#>
<#@ import namespace="System.IO"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
<#+
class Manager
{public struct Block {public int Start, Length;public String Name,OutputPath;}public List<Block> blocks = new List<Block>();public Block currentBlock;public Block footerBlock = new Block();public Block headerBlock = new Block();public ITextTemplatingEngineHost host;public ManagementStrategy strategy;public StringBuilder template;public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader) {this.host = host;this.template = template;strategy = ManagementStrategy.Create(host);}public void StartBlock(String name,String outputPath) {currentBlock = new Block { Name = name, Start = template.Length ,OutputPath=outputPath};}public void StartFooter() {footerBlock.Start = template.Length;}public void EndFooter() {footerBlock.Length = template.Length - footerBlock.Start;}public void StartHeader() {headerBlock.Start = template.Length;}public void EndHeader() {headerBlock.Length = template.Length - headerBlock.Start;}    public void EndBlock() {currentBlock.Length = template.Length - currentBlock.Start;blocks.Add(currentBlock);}public void Process(bool split) {String header = template.ToString(headerBlock.Start, headerBlock.Length);String footer = template.ToString(footerBlock.Start, footerBlock.Length);blocks.Reverse();foreach(Block block in blocks) {String fileName = Path.Combine(block.OutputPath, block.Name);if (split) {String content = header + template.ToString(block.Start, block.Length) + footer;strategy.CreateFile(fileName, content);template.Remove(block.Start, block.Length);} else {strategy.DeleteFile(fileName);}}}
}
class ManagementStrategy
{internal static ManagementStrategy Create(ITextTemplatingEngineHost host) {return (host is IServiceProvider) ? new VSManagementStrategy(host) : new ManagementStrategy(host);}internal ManagementStrategy(ITextTemplatingEngineHost host) { }internal virtual void CreateFile(String fileName, String content) {File.WriteAllText(fileName, content);}internal virtual void DeleteFile(String fileName) {if (File.Exists(fileName))File.Delete(fileName);}
}class VSManagementStrategy : ManagementStrategy
{private EnvDTE.ProjectItem templateProjectItem;internal VSManagementStrategy(ITextTemplatingEngineHost host) : base(host) {IServiceProvider hostServiceProvider = (IServiceProvider)host;if (hostServiceProvider == null)throw new ArgumentNullException("Could not obtain hostServiceProvider");EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));if (dte == null)throw new ArgumentNullException("Could not obtain DTE from host");templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);}internal override void CreateFile(String fileName, String content) {base.CreateFile(fileName, content);//((EventHandler)delegate { templateProjectItem.ProjectItems.AddFromFile(fileName); }).BeginInvoke(null, null, null, null);}internal override void DeleteFile(String fileName) {((EventHandler)delegate { FindAndDeleteFile(fileName); }).BeginInvoke(null, null, null, null);}private void FindAndDeleteFile(String fileName) {foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) {if (projectItem.get_FileNames(0) == fileName) {projectItem.Delete();return;}}}
}#>

(3)创建实体类运行时文本模版

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension="/" #>
<#@ assembly name="System.Core.dll" #>
<#@ assembly name="System.Data.dll" #>
<#@ assembly name="System.Data.DataSetExtensions.dll" #>
<#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ include file="$(ProjectDir)DbHelper.ttinclude"  #>
<#@ include file="$(ProjectDir)ModelAuto.ttinclude"  #>
<# var manager = new Manager(Host, GenerationEnvironment, true); #>
<# var OutputPath1 =Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Host.TemplateFile+"..")+"..")+"..");OutputPath1=Path.Combine(OutputPath1,"H5.Framwork","Models_New");if (!Directory.Exists(OutputPath1)){Directory.CreateDirectory(OutputPath1);}
#>
<# foreach (var item in DbHelper.GetDbTablesNew(config.ConnectionString, config.DbDatabase,config.TableName)){var tableName=item.ToString();manager.StartBlock(tableName+".cs",OutputPath1);//文件名#>
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace H5.Framwork.Model
{///<summary>///<#=tableName#>///</summary>[Table("<#=tableName#>")]    public class <#=tableName#>{<# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#>/// <summary>/// <#= column.Remark == "" ? column.ColumnName : column.Remark.Replace("\r\n"," ") #>/// </summary><# if(column.IsPrimaryKey) {#>[Key]<#}#><# if(!column.IsNullable) {#>[Required]<# }#>public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; }<#}#> }
}
<#manager.EndBlock(); }manager.Process(true);#>

我们这里是在同个项目中的Models_New文件夹生产实体类

最后只需右键运行自定义工具就可以快速生成实体类了,运行代码上面的gif图所示

当然t4模版不仅仅只能生成实体类还能生产其他固定代码,其他的我们下一次来讲解

C# T4模板在项目中的使用相关推荐

  1. 从零开始编写自己的C#框架(14)——T4模板在逻辑层中的应用(三)

    原本关于T4模板原想分5个章节详细解说的,不过因为最近比较忙,也不想将整个系列时间拉得太长,所以就将它们整合在一块了,可能会有很多细节没有讲到,希望大家自己对着代码与模板去研究. 本章代码量会比较大, ...

  2. .NET中关于T4模板的使用

    文章目录 介绍 简单说下什么是t4模版 具体使用方式 TransformText方法 自定义T4模板引擎 两种方式的比较 总结 介绍 最近工作中需要按一定的模板模型生成指定的文件,虽然可以直接拼接字符 ...

  3. MVC中使用T4模板

    一.原文地址 大佬的链接:http://www.cnblogs.com/heyuquan/archive/2012/07/26/2610959.html 二.图片释义 1.简单示例,对基本的模块标记 ...

  4. Django项目准备和配置(MVT图解、创建项目和应用、更换解释器、安装应用、本地化、模板路径、项目中匹配urls、应用中匹配urls.py、准备视图、开启服务器、修改DATABAS配置信息)

    Django模型主要包含: 模型配置 数据的增删改 增:book = BookInfo() book.save() 和BookInfo.objects.create() 删:book.delete() ...

  5. IDEA下,如何在java项目中新增jsp模板文件

    IDEA下,如何在java项目中新增jsp模板文件 大家会不会有这样的烦恼,就是当想要创建一个jsp模板文件的时候,右键new的时候找不到JSP选项. 这是因为在创建项目的时候没有选中Web Appl ...

  6. Java项目中利用Freemarker模板引擎导出--生成Word文档

    应邀写的一篇文章:Java项目中利用Freemarker模板引擎导出--生成Word文档 资源下载:https://download.csdn.net/download/weixin_41367523 ...

  7. HBuilder X中新建uni-app项目中的Hello uni-app模板后,自己添加的页面为什么运行时不显示,找不到入口?

    在HBuilderX中新建了一个uni-app项目,然后选择了Hello uni-app模板进行测试编译,发现自己在pages目录下新建一个my-test文件夹后在此文件下进行编写测试,发现运行起来没 ...

  8. 项目中前端ftl模板了解

    在项目中如前端页面list.ftl,代码部分如下: <!DOCTYPE html> <html> <#import "/spring.ftl" as ...

  9. 下载项目中的excel模板文件.xlsx后,无法打开的问题

    题外话:通常在导入Excel文件时,会定义一套模板文件,让用户按此模板文件规定的内容进行填写,可以高效导入数据的同时,也利用Excel本身的功能,制定一些规则提示.有效性校验等,减少在代码中校验的繁琐 ...

最新文章

  1. 程序员的编程能力与编程年龄
  2. Python调用大漠插件
  3. python中lambda函数对时间排序_python – 使用lambda函数排序()
  4. 不要被约束的意思_俗话说:“娶妻不娶颧骨高,嫁汉不嫁连眉梢”,到底什么意思?...
  5. [vue] Vue.observable你有了解过吗?说说看
  6. Spring 3 MVC and JSR303 @Valid example
  7. Event 事件对象 (target)帆软修改提示框样式
  8. mac如何修改hosts文件
  9. 谷歌浏览器不能用_正在用 Chrome 或 Edge 浏览器的你,不能错过这亿个好用插件...
  10. python使用pip离线安装库(本机环境)
  11. NETWARE系统加入服务器,如何在 Netware 服务器中安装多块网卡
  12. clickhouse总结
  13. 2022钉钉发布会|云钉低代码新模式、新能力、新机遇
  14. 人际交往三个常见问题
  15. [Android Studio]开发APP应用出现软件程序打开闪退的排错
  16. Qt图形视图QGraphicsItem类
  17. android 硬币翻转动画,使用Android标准动画显示正在翻转的硬币的两面
  18. 侯捷-C++面向对象高级开发(头文件与类的声明,构造函数,参数传递与返回值)
  19. 强制关闭极域电子教室学生端
  20. 环保数据采集仪_环保采集仪_环保数据采集器

热门文章

  1. eclipse的workspace删除
  2. 如何成为快手尬舞王?HUAWEI HiAI了解一下!
  3. 开放报名|顶尖专家联合打造,首个系统化AI大模型前沿技术讲习班
  4. 【UE4 第一人称射击游戏】07-添加“AK47”武器
  5. 微信域名防封解决方案
  6. Mac通过istats查看CPU温度、风扇转速
  7. FAST-LIO, ikd-Tree, FAST-LIO2, FASTER-LIO论文总结
  8. 深度学习在自闭症谱系障碍神经成像诊断和康复中的应用
  9. C语言实现实数和复数矩阵及其各种运算(三)
  10. C/C++开发,c/c++如何实现根据磁盘空间管理自己的日志文件案例