创建代码生成器可以很简单:如何通过T4模板生成代码?[下篇]
在《上篇》中我们通过T4模板为我们指定的数据表成功生成了我们需要的用于添加、修改和删除操作的存储过程。但是这是一种基于单个文件的解决方案,即我们必须为每一个生成的存储过程建立一个模板。如果我们提供一种基于多文件的代码生成方式,将会为编程人员带来极大的便利。借助于T4 ToolBox这个开源工具箱,多文件的SQL Generator的实现变得异常简单。[文中的例子可以从这里下载]
一、多文件代码生成器会带来多大的便利?有的时候,基于单个数据表的存储过程生成方式我们依然觉得不方便。如果我们能够在T4模板文件中指定的数据表的列表,让我们的SQL Generator为列表的每一个数据表都生成CUD三个存储过程,这样的方式更加具有吸引力。如右图所示(点击看大图),一个订单模块包含两个具有主子关系的两张表(T_ORDER和T_ORDER_DETAIL),现在我们在一个T4模板中指定这两个表明,通过SQL Generator可以帮助我们生成6个包含存储过程的.sql附属文件。 甚至有的时候我们连数据表列表都无需指定,让SQL Generator为所有的表都生成相应的存储过程。我的例子中没有提供这样的功能,但是实现自来不会存在任何问题。 二、创建自定义的Generator在《上篇》中我创建了一个抽象的ProcedureTemplate类,以及三个基于生成CUD存储过程的具体ProcedureTemplate:InsertProcedureTemplate、UpdateProcedureTemplate和DeleteProcedureTemplate。它们都将直接服务于我们今天将要提供的基于多文件的SQL Generator。 在《上篇》中,这四个Template分别定义在4个不同的TT文件中,3个具体的ProcedureTemplate通过<#@include>指令将抽象ProcedureTemplate模板文件包含过来。由于我们将要创建的T4模板将会使用到这四个类,如果我们用四个<#@include>指令将四个TT文件包含过来,由于T4引擎将会导致对ProcedureTemplate的4次包含,最好将会导致变异问题。个人觉得这应该算是T4引擎解析包含关系的一个局限性,为了解决这个问题我们不得不抽象的ProcedureTemplate和三个具体的ProcedureTemplate都合并成一个TT文件。 T4 ToolBox为类库中为了提供了一个抽象的T4Toolbox.Generator类用于实现多文件的代码生成。为此我们创建一个TT模板文件,定义了如下一个继承自该类的ProcedureGenerator。ProcedureGenerator的核心是通过属性Templates定义的类型为IEnumerable<ProcedureTemplate>的ProcedureTemplate列表,这个列表在存储过程中进行初始化。而对于ProcedureGenerator的构造函数,处理定义了一个表示数据库连接字符串的databaseName的参数外,并以数组参数的形式指定了生成的存储过程基于的数据表名的列表。 <#@ import namespace="System.Collections.Generic" #> <#@ include file="ProcedureTemplate.tt" #>
<#+ public class ProcedureGenerator : Generator { public IEnumerable<ProcedureTemplate> Templates{get; private set;} { if(null == tableNames || tableNames.Length == 0) { throw new ArgumentNullException("tableNames"); } } { yield return new InsertProcedureTemplate(databaseName,tableName); new DeleteProcedureTemplate(databaseName,1); font-size: 8pt; overflow: visible'> } foreach(ProcedureTemplate tempalte in this.Templates) tempalte.RenderToFile(tempalte.GetProcedureName() + ".sql");
} #> 真正的存储过程的T-SQL脚本实现在重写的RunCore中。由于具体的文本转化逻辑都定义在了ProcedureTemplate中了,所以在这里我们需要遍历的ProcedureTemplate集合中每一个Template对象,调用RenderToFile方法将相应的存储过程的脚本写入以存储过程命名同名的.sql文件中。 三、ProcedureGenerator如何被使用?我们最后来看看我们创建的ProcedureGenerator最终如何被应用于具体的代码生成。其实很简单,我们只需要创建相应的模板文件,通过<#@include>将定义ProcedureGenerator类的TT文件包含近来,最后以代码语句调用块(<#StatementCode#>)的形式实力化该对象,并调用Run方法即可。在构造函数中指定数据库连接字符串的名称和数据表名的列表。下面是基于但表的T4模板。 <#@ template language="C#" hostSpecific="true" debug="true" #>
<# new ProcedureGenerator("TestDb",1)">"T_PRODUCT").Run(); #> 下面是基于多表的T4模板: #>
当你代码生成工作执行之后,会多出一个与TT文件同名的附属文件,你需要手工删除掉它。 从数据到代码——通过代码生成机制实现强类型编程[上篇] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc-3 – ASP.NET MVC:如何返回304“未修改”状态
- asp.net – 无法让Web API在VS 2010或2012中运行
- asp.net-mvc – 静态内容的MVC客户端缓存不起作用
- ABP(ASP.NET Boilerplate Project)快速入门
- 使用ASP.NET MVC时从WebForm访问HtmlHelpers
- asp.net三层架构增删改查
- asp.net – 在实体框架中使用PersianCalendar作为表列的正确
- 单元测试 – Stubbing或Mocking ASP.NET Web API HttpClien
- ASP.NET Identity会话cookie的安全性如何?
- asp.net-mvc – Asp.net Mvc:Ninject – IPrincipal
- asp.net-mvc-4 – 返回Web API中的自定义错误对象
- asp.net-mvc-3 – 用于生成单行文本的Razor
- asp.net – 使用带有模拟的Windows身份验证的Web
- asp.net-mvc-3 – ASP.NET MVC – 如何防止双击提
- .net – 不能使用moles来模拟MVC框架
- asp.net-mvc – 编译错误“无法在Web部署项目中加
- asp.net-mvc – 看起来你忘了注册HTTP模块与Wind
- asp.net-mvc-3 – Autofac属性注入
- asp.net-mvc-2 – 具有异常参数的ModelState.Add
- 在asp.net中排序gridview的列c#