在《上篇》中我们通过T4模板为我们指定的数据表成功生成了我们需要的用于添加、修改和删除操作的存储过程。但是这是一种基于单个文件的解决方案,即我们必须为每一个生成的存储过程建立一个模板。如果我们提供一种基于多文件的代码生成方式,将会为编程人员带来极大的便利。借助于T4 ToolBox这个开源工具箱,多文件的SQL Generator的实现变得异常简单。[文中的例子可以从这里下载]

目录
一、多文件代码生成器会带来多大的便利?
二、创建自定义的Generator
三、ProcedureGenerator如何被使用?

一、多文件代码生成器会带来多大的便利?

我们先来直观的感受一下较之《上篇》提供的单一文件的代码生成器,基于多文件的代码生成解决方案会为开发人员带来多大的便利。 同样对于《上篇》创建的数据表T_PRODUCT,之前我们为了生成三个不同的存储过程,我们不得已需要创建3个不同的T4模板文件。实际上我们更需要的方式只需要创建一个T4模板,让我们的SQL Generator自动为我们生成3个包含相应存储过程的.sql附属文件,如左图所示(点击看大图)。

有的时候,基于单个数据表的存储过程生成方式我们依然觉得不方便。如果我们能够在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" #>
<#@ include file="T4Toolbox.tt" #>
<#+
public class ProcedureGenerator : Generator
{
    public IEnumerable<ProcedureTemplate> Templates{get; private set;}
  
    public ProcedureGenerator(string databaseName, params string[] tableNames)
    {
        if(null == tableNames || tableNames.Length == 0)
        {
            throw new ArgumentNullException("tableNames");
        }    
        
        this.Templates = InitlizeTemplates(databaseName,tableNames);
    }
    
    private IEnumerable<ProcedureTemplate> InitlizeTemplates(string databaseName, string[] tableNames)
    {        
        foreach(string tableName in tableNames)
        {
            yield return new InsertProcedureTemplate(databaseName, tableName);
            yield return new UpdateProcedureTemplate(databaseName, tableName);
            yield return new DeleteProcedureTemplate(databaseName, tableName);
        }
    }
    
    protected override void RunCore()
    {
        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" #>
<#@ include file="Templates\ProcedureGenerator.tt" #>
<#
   new ProcedureGenerator("TestDb","T_PRODUCT").Run();
#>

下面是基于多表的T4模板:

<#@ template language="C#" hostSpecific="true" debug="true" #>
<#@ include file="Templates\ProcedureGenerator.tt" #>
<#
   new ProcedureGenerator("TestDb","T_ORDER","T_ORDER_DETAIL").Run();
#>

当你代码生成工作执行之后,会多出一个与TT文件同名的附属文件,你需要手工删除掉它。

从数据到代码——通过代码生成机制实现强类型编程[上篇]
从数据到代码——通过代码生成机制实现强类型编程[下篇]
从数据到代码——基于T4的代码生成方式
创建代码生成器可以很简单:如何通过T4模板生成代码?[上篇]
创建代码生成器可以很简单:如何通过T4模板生成代码?[下篇]

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文链接

创建代码生成器可以很简单:如何通过T4模板生成代码?[下篇]相关推荐

  1. 创建代码生成器可以很简单:如何通过T4模板生成代码?[上篇]

    在<基于T4的代码生成方式>中,我对T4模板的组成结构.语法,以及T4引擎的工作原理进行了大体的介绍,并且编写了一个T4模板实现了如何将一个XML转变成C#代码.为了让由此需求的读者对T4 ...

  2. t4b代码生成_Ef+T4模板实现代码快速生成器

    效果如图,demo(点击demo可下载案例) 项目结构如图 T4BLL添加BLL.tt文件: T4Model添加Model文件: T4DAL添加DAL.tt文件: T4DAL 添加ADO.NET En ...

  3. t4模板生成html,强大的代码生成器——T4模板

    T4 Editor工具下载地址 tangible T4 Editor 2.5.0 plus modeling tools for VS 2019 https://marketplace.visuals ...

  4. [转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

    本文转自:http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html 〇.目录 一.前言 二.工具准备 三.T4代码生成预热 (一) 单文件生成:Hello ...

  5. 使用 Source Generator 代替 T4 动态生成代码

    使用 Source Generator 代替 T4 动态生成代码 Intro 在 Source Generator 出现之前有一些重复性的代码,我会使用 T4 去生成,这样就可以一定程度上避免复制粘贴 ...

  6. 在Visual Studio中使用T4 Templates 生成代码

    在没有看过Hilton Giesenow(How Do I: Create and Use T4 Templates.)的视频之前,我还没意识到在Visual Studio 2008 中使用T4是何等 ...

  7. 使用Runnable接口创建线程,很简单

    大家好,今天分享.使用Runnable接口创建线程 首先Java创建线程可以通过三种方法: 即: 1.继承Thread类创建线程类(重点) 2.通过Runnable接口创建线程类(重点) 3.通过Ca ...

  8. mysql+代码备份,一个很简单的MYSQL数据库备份脚本代码

    假设有三个库 m_site,m_bbs,m_cms. #!/bin/sh # # MySQL Backup Scripts. # Created by david. # # Created time: ...

  9. Linq to Oracle 使用教程(八)使用 T4 模版生成代码

    点击这里返回目录   禁用原来的代码生成(可选步骤) 选择 Northwind.admf 文件,在属性窗口中,将 Custom Tool 属性设置为空,原来值为 ALinqCodeGenerator ...

最新文章

  1. 七夕节,程序员们都怎么哄女朋友开心?
  2. 如何通过session控制单点登录
  3. ux设计师怎样找同类产品_没有预算? 别找借口。 便宜的UX上的UX 2:让我们开始构建。...
  4. 玩转oracle 11g(22):ora-01691和修改密码过期时间
  5. android netty导入_Android Netty框架的使用
  6. python设计模式17-中介者模式
  7. Android用按钮确定单选框,Android RadioButton单选框的使用方法
  8. 蓝桥杯 ALGO-123 算法训练 A+B problem
  9. AutoCAD使用技巧
  10. html中写自增数字,CSS 小技巧:counter 实现有序列表编号自增
  11. 可以看下是什么问题吗
  12. opencv调取摄像头
  13. 四川传媒学院计算机应用技术分数,四川传媒学院历年各专业录取文化最低控制分数线一览表...
  14. PLC软件申请软件著作权登记指南(新申请)
  15. PLC与伺服电机连接
  16. 神舟 桌面显示计算机,神舟(Hasee)笔记本电脑重装系统步骤详解
  17. xmlspy使用必备的技巧
  18. 计算力学:显式积分与隐式积分小结
  19. 微信:一个必须研究的产品
  20. java转大数据方向如何走?

热门文章

  1. HTML5绝对定位图片合成,HTML5 绝对定位的问题
  2. 大年30还多少天_2020余额不足30天!年初许下的愿望你实现了多少?
  3. 【git】几大区概念
  4. iOS的类方法和实例方法区别与使用
  5. swift_036(Swift之第三方库SwiftyJSON篇)
  6. java json 去重_js操作两个json数组合并、去重,以及删除某一项元素
  7. django 整理一
  8. Verilog中实现电平检测
  9. chrome浏览器测试插件postman安装
  10. java019异常、File类