博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从零开始编写自己的C#框架(13)——T4模板在逻辑层中的应用(二)
阅读量:4607 次
发布时间:2019-06-09

本文共 17035 字,大约阅读时间需要 56 分钟。

  最近这段时间特忙,公事私事,忙得有时都没时间打开电脑了,这两周只能尽量更新,以后再将章节补回来。

 

  直接进入主题,通过上一章节,大家明白了怎么使用模板类编写T4模板,本章进的是一些简单技巧的应用

  1、首先创建一个Test2.tt模板

  

  2、然后修改模板内容为下面代码

  这些代码与上一章最后面的那个差不多,只是修改了输出文件名、命名空间、类名、类属性(partial)和一个单例获取函数

1 <#@ template debug="false" hostspecific="True" language="C#" #> 2 <#@ output extension=".cs" encoding="utf-8" #> 3 <#@ include file="SQLServer.ttinclude" #> 4 <#@ include file="MultipleOutputHelper.ttinclude"#>  5  6 <# 7     //获取所有表与视图 8     var tables = LoadTables(); 9     //创建多文件生成实体10     var manager = Manager.Create(Host, GenerationEnvironment);  11 12     //遍历所有表13     foreach(var tbl in tables){14         //判断当前表名是否是禁用名称(禁用的名称可以在Settings.ttinclude文件的ExcludeTables字符串数据中进行添加)15         if(!ExcludeTables.Contains(tbl.Name))16         {17             // 设置输出的文件名18             manager.StartNewFile(tbl.ClassName+"Bll.cs");19 #> 20 using System;21 22 namespace Solution.Logic {23 24     public partial class <#=tbl.CleanName#>Bll {25         26         #region 单例模式27         //定义单例实体28         private static <#=tbl.Name#>Bll _<#=tbl.Name#>Bll = null;29 30         /// 31         /// 获取本逻辑类单例32         /// 33         /// 
34 public static <#=tbl.Name#>Bll GetInstence() {35 if (_<#=tbl.Name#>Bll == null) {36 _<#=tbl.Name#>Bll = new <#=tbl.Name#>Bll();37 }38 return _<#=tbl.Name#>Bll;39 }40 #endregion41 42 }43 44 }45 46 47 <# 48 // 输出文件结束49 manager.EndBlock();50 } //if(!ExcludeTables.Contains(tbl.Name)) 判断结束51 52 }// end foreach53 54 // 执行编译,生成文件55 manager.Process(true); 56 #>

  运行模板,测试看看效果

  

  

  从上面添加函数的方法可以看出,对于常用的函数,都可以在模板中进行添加后,直接生成出来,这样就减少了程序员很大的工作量了

 

  3、用上面方法确实可以解决很大部分的问题,但对于一些特殊的函数直接这样写就不行了,比如我们想生成一个删除指定外键Id的函数,由于有的表有外键有的没有,那么就要用上一些简单的判断来处理了

  

1 <#@ template debug="false" hostspecific="True" language="C#" #> 2 <#@ output extension=".cs" encoding="utf-8" #> 3 <#@ include file="SQLServer.ttinclude" #> 4 <#@ include file="MultipleOutputHelper.ttinclude"#>  5  6 <# 7     //获取所有表与视图 8     var tables = LoadTables(); 9     //创建多文件生成实体10     var manager = Manager.Create(Host, GenerationEnvironment);  11 12     //遍历所有表13     foreach(var tbl in tables){14         //判断当前表名是否是禁用名称(禁用的名称可以在Settings.ttinclude文件的ExcludeTables字符串数据中进行添加)15         if(!ExcludeTables.Contains(tbl.Name))16         {17             // 设置输出的文件名18             manager.StartNewFile(tbl.ClassName+"Bll.cs");19 #> 20 using System;21 using Solution.DataAccess.DataModel;22 using Solution.DataAccess.DbHelper;23 24 namespace Solution.Logic {25 26     public partial class <#=tbl.CleanName#>Bll {27         28         #region 单例模式29         //定义单例实体30         private static <#=tbl.Name#>Bll _<#=tbl.Name#>Bll = null;31 32         /// 33         /// 获取本逻辑类单例34         /// 35         /// 
36 public static <#=tbl.Name#>Bll GetInstence() {37 if (_<#=tbl.Name#>Bll == null) {38 _<#=tbl.Name#>Bll = new <#=tbl.Name#>Bll();39 }40 return _<#=tbl.Name#>Bll;41 }42 #endregion43 44 45 <#46 foreach(var col in tbl.Columns){47 //判断字段名称中是否包含“_Id”这个字符串,且字段类型为int或long的,则生成对应的删除函数48 if (col.CleanName.IndexOf("_Id") >= 0 && (col.SysType == "int" || col.SysType == "long"))49 {50 #>51 #region 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录52 /// 53 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录54 /// 55 /// 记录的主键值56 public void DeleteBy<#=col.CleanName#>(int id) {57 //删除58 <#=tbl.Name#>.Delete(x => x.<#=col.CleanName#> == id);59 }60 61 /// 62 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录63 /// 64 /// 记录的主键值65 public void DeleteBy<#=col.CleanName#>(int[] id) {66 if (id == null) return;67 //将数组转为逗号分隔的字串68 var str = string.Join(",", id);69 70 //设置Sql语句71 var sql = "delete from <#=tbl.Name#> where <#=col.CleanName#> in (" + str + ")";72 73 //删除74 var deleteHelper = new DeleteHelper();75 deleteHelper.Delete(sql);76 }77 #endregion78 79 <#80 }81 }82 #>83 }84 85 }86 87 88 <# 89 // 输出文件结束90 manager.EndBlock();91 } //if(!ExcludeTables.Contains(tbl.Name)) 判断结束92 93 }// end foreach94 95 // 执行编译,生成文件96 manager.Process(true); 97 #>

  运行模板,测试看看效果

  

  

  4、同理,我们可以通过判断,生成获取指定名称的字段值和生成删除图片函数等,这些都可以根据你的需要去生成

  

1 <#@ template debug="false" hostspecific="True" language="C#" #>  2 <#@ output extension=".cs" encoding="utf-8" #>  3 <#@ include file="SQLServer.ttinclude" #>  4 <#@ include file="MultipleOutputHelper.ttinclude"#>   5   6 <#  7     //获取所有表与视图  8     var tables = LoadTables();  9     //创建多文件生成实体 10     var manager = Manager.Create(Host, GenerationEnvironment);   11  12     //遍历所有表 13     foreach(var tbl in tables){ 14         //判断当前表名是否是禁用名称(禁用的名称可以在Settings.ttinclude文件的ExcludeTables字符串数据中进行添加) 15         if(!ExcludeTables.Contains(tbl.Name)) 16         { 17             // 设置输出的文件名 18             manager.StartNewFile(tbl.ClassName+"Bll.cs"); 19 #>  20 using System; 21 using Solution.DataAccess.DataModel; 22 using Solution.DataAccess.DbHelper; 23  24 namespace Solution.Logic { 25  26     public partial class <#=tbl.CleanName#>Bll { 27          28         #region 单例模式 29         //定义单例实体 30         private static <#=tbl.Name#>Bll _<#=tbl.Name#>Bll = null; 31  32         ///  33         /// 获取本逻辑类单例 34         ///  35         /// 
36 public static <#=tbl.Name#>Bll GetInstence() { 37 if (_<#=tbl.Name#>Bll == null) { 38 _<#=tbl.Name#>Bll = new <#=tbl.Name#>Bll(); 39 } 40 return _<#=tbl.Name#>Bll; 41 } 42 #endregion 43 44 <# 45 foreach(var col in tbl.Columns){ 46 //判断字段名称中是否包含“_Id”这个字符串,且字段类型为int或long的,则生成对应的删除函数 47 if (col.CleanName.IndexOf("_Id") >= 0 && (col.SysType == "int" || col.SysType == "long")) 48 { 49 #> 50 #region 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录 51 /// 52 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录 53 /// 54 /// 记录的主键值 55 public void DeleteBy<#=col.CleanName#>(int id) { 56 //删除 57 <#=tbl.Name#>.Delete(x => x.<#=col.CleanName#> == id); 58 } 59 60 /// 61 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录 62 /// 63 /// 记录的主键值 64 public void DeleteBy<#=col.CleanName#>(int[] id) { 65 if (id == null) return; 66 //将数组转为逗号分隔的字串 67 var str = string.Join(",", id); 68 69 //设置Sql语句 70 var sql = "delete from <#=tbl.Name#> where <#=col.CleanName#> in (" + str + ")"; 71 72 //删除 73 var deleteHelper = new DeleteHelper(); 74 deleteHelper.Delete(sql); 75 } 76 #endregion 77 78 <# 79 } 80 //判断字段名称中是否包含“Name”这个字符串,且字段类型为string 81 else if (col.CleanName.IndexOf("Name") >= 0 && col.SysType == "string") 82 { 83 #> 84 #region 获取<#=col.CleanName #>字段值 85 /// 86 /// 获取<#=col.CleanName #>字段值 87 /// 88 /// 主键Id 89 ///
90 public string Get<#=col.CleanName #>(int pkValue) 91 { 92 //从数据库中查询 93 var model = <#=tbl.Name#>.SingleOrDefault(x => x.Id == pkValue); 94 return model == null ? "" : model.<#=col.CleanName #>; 95 } 96 #endregion 97 98 <# 99 }100 //判断字段名称中是否包含“Img”这个字符串,且字段类型为string101 else if (col.CleanName.IndexOf("Img") >= 0 && col.SysType == "string") 102 {103 #>104 #region 删除<#=col.CleanName #>字段存储的对应图片105 /// 删除<#=col.CleanName #>字段存储的对应图片106 /// 主键Id107 public void Del<#=col.CleanName #>(int pkValue) {108 try {109 //添加删除语句110 }111 catch (Exception e) {112 //出现异常,保存出错日志信息113 //添加保存出错日志语句114 }115 }116 #endregion117 118 <#119 120 }121 }122 #>123 }124 125 }126 127 128 <# 129 // 输出文件结束130 manager.EndBlock();131 } //if(!ExcludeTables.Contains(tbl.Name)) 判断结束132 133 }// end foreach134 135 // 执行编译,生成文件136 manager.Process(true); 137 #>

  运行模板,测试看看效果

  

 

  5、有时候我们会存在一些特殊的需求,有些表或字段要进行过滤操作,这时我们就可以使用一些简单的过滤判断处理

  比如我们对于Manager_Id与Manager_Name这两个字段是不需要生成对应函数的,那么我们就可以加个过滤处理

  首先在Settings.ttinclude文件中创建一个字符串数组变量,并赋值

  

  然后在模板中的循环语句中添加判断

  

  运行模板,测试看看效果

  

  对比第4点的图就可以看到,已经少了两个函数了

  而表名过滤,在上一章节的内容中已经包含了,请看下图

  

  只要在Settings.ttinclude文件中的ExcludeTables变量中添加你想过滤的表名称就可以了

 

  当然我们还可以写出更多的扩展,这些需要发挥你的想象力,生成更多常用函数,使你从复制粘贴中解放出来,当然函数有变动时,也只需要改一下模板就可以了,方便快捷

 

  6、对于常用功能来说,前面的生成方式都可以解决,但有时候有些功能直接生成的方式解决不了,那么父类(基类)与虚函数的运用可以帮我们解决很多程序调用的问题。

  比如我们使用IIS缓存,在对记录进行添加、删除与修改操作时,必须同步删除缓存。看到这个需求,可能有的朋友就会说,这很简单啊,直接生成一个缓存删除函数就可以了。是的,这是一种处理方法,但还会存在很多特殊情况,有些时候,我们在自定义函数中也会用到一些缓存,这些缓存并不存在模板中,那么想要模板里的程序在清空模板缓存后,也能自动帮我们清除自定义缓存的话该怎么实现呢?不可能要让我们在相关程序调用的方法中手动添加吧,如果调用的地方太多的话,就很容易忘记了。而我们有一种比较好的解决方式,那就是使用父类(基类),在基类中实现一个删除缓存的虚函数,模板类继承基类后,可以在那些执行添加、删除与修改的函数中直接调用虚函数,而对于这些个性化的删除操作,我们只需要使用override修饰符重写该函数,就可以实现自动删除缓存的功能了。

  具体操作方法请看下面步骤:

  首先创建一个基类

  

  创建一个虚函数

  

  然后再模板中让模板类继承基类,并实现添加、修改与删除方法,在方法中调用删除缓存函数

  

1 <#@ template debug="false" hostspecific="True" language="C#" #>  2 <#@ output extension=".cs" encoding="utf-8" #>  3 <#@ include file="SQLServer.ttinclude" #>  4 <#@ include file="MultipleOutputHelper.ttinclude"#>   5   6 <#  7     //获取所有表与视图  8     var tables = LoadTables();  9     //创建多文件生成实体 10     var manager = Manager.Create(Host, GenerationEnvironment);   11  12     //遍历所有表 13     foreach(var tbl in tables){ 14         //判断当前表名是否是禁用名称(禁用的名称可以在Settings.ttinclude文件的ExcludeTables字符串数据中进行添加) 15         if(!ExcludeTables.Contains(tbl.Name)) 16         { 17             // 设置输出的文件名 18             manager.StartNewFile(tbl.ClassName+"Bll.cs"); 19 #>  20 using System; 21 using System.Linq.Expressions; 22 using Solution.DataAccess.DataModel; 23 using Solution.DataAccess.DbHelper; 24  25 namespace Solution.Logic  26 { 27  28     public partial class <#=tbl.CleanName#>Bll : LogicBase 29     { 30          31         #region 单例模式 32         //定义单例实体 33         private static <#=tbl.Name#>Bll _<#=tbl.Name#>Bll = null; 34  35         ///  36         /// 获取本逻辑类单例 37         ///  38         /// 
39 public static <#=tbl.Name#>Bll GetInstence() 40 { 41 if (_<#=tbl.Name#>Bll == null) 42 { 43 _<#=tbl.Name#>Bll = new <#=tbl.Name#>Bll(); 44 } 45 return _<#=tbl.Name#>Bll; 46 } 47 #endregion 48 49 #region 添加与编辑<#=tbl.Name#>表记录 50 /// 51 /// 添加与编辑<#=tbl.Name#>记录 52 /// 53 /// <#=tbl.Name#>表实体 54 public void Save(<#=tbl.Name#> model) 55 { 56 try { 57 //保存 58 model.Save(); 59 60 //删除缓存 61 DelCache(); 62 63 //添加用户访问记录 64 //UseLogBll.GetInstence().Save("{0}" + (model.Id == 0 ? "添加" : "编辑") + "<#=tbl.Name#>记录成功,ID为【" + model.Id + "】"); 65 } 66 catch (Exception e) { 67 //var result = "执行<#=tbl.Name#>Bll.Save()函数出错!"; 68 69 //出现异常,保存出错日志信息 70 //CommonBll.WriteLog(result, e, false); 71 } 72 } 73 #endregion 74 75 #region 删除<#=tbl.Name#>表记录 76 /// 77 /// 删除<#=tbl.Name#>表记录 78 /// 79 /// 记录的主键值 80 public void Delete(int id) { 81 //设置Sql语句 82 var sql = "delete from <#=tbl.Name#> where Id = " + id; 83 84 //删除 85 var deleteHelper = new DeleteHelper(); 86 deleteHelper.Delete(sql); 87 88 //删除缓存 89 DelCache(); 90 91 //添加用户操作记录 92 //UseLogBll.GetInstence().Save("{0}删除了<#=tbl.Name#>表id为【" + id + "】的记录!"); 93 } 94 95 /// 96 /// 删除<#=tbl.Name#>表记录 97 /// 98 /// 记录的主键值 99 public void Delete(int[] id) {100 if (id == null) return;101 //将数组转为逗号分隔的字串102 var str = string.Join(",", id);103 104 //设置Sql语句105 var sql = "delete from <#=tbl.Name#> where Id in (" + str + ")";106 107 //删除108 var deleteHelper = new DeleteHelper();109 deleteHelper.Delete(sql);110 111 //删除缓存112 DelCache();113 114 //添加用户操作记录115 //UseLogBll.GetInstence().Save("{0}删除了<#=tbl.Name#>表id为【" + str + "】的记录!");116 }117 118 /// 119 /// 获取数据表中的某个值——从数据库中查询,如果使用了缓存,删除成功后会清空本表的所有缓存记录,然后重新加载进缓存120 /// 121 /// 条件语句122 ///
123 public void Delete(Expression
<<#=tbl.Name#>, bool>> expression)124 {125 //执行删除126 <#=tbl.Name#>.Delete(expression);127 128 //删除缓存129 DelCache();130 131 //添加用户操作记录132 //UseLogBll.GetInstence().Save(page, "{0}删除了<#=tbl.Name#>表记录!");133 }134 #endregion135 136 <#137 foreach(var col in tbl.Columns)138 {139 //进行过滤判断,指定的字段名称不做处理140 if (ExcludeFields.Contains(col.CleanName))141 continue;142 143 //判断字段名称中是否包含“_Id”这个字符串,且字段类型为int或long的,则生成对应的删除函数144 if (col.CleanName.IndexOf("_Id") >= 0 && (col.SysType == "int" || col.SysType == "long"))145 {146 #>147 #region 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录148 ///
149 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录150 /// 151 ///
记录的主键值152 public void DeleteBy<#=col.CleanName#>(int id) 153 {154 //删除155 <#=tbl.Name#>.Delete(x => x.<#=col.CleanName#> == id);156 }157 158 ///
159 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录160 /// 161 ///
记录的主键值162 public void DeleteBy<#=col.CleanName#>(int[] id) 163 {164 if (id == null) return;165 //将数组转为逗号分隔的字串166 var str = string.Join(",", id);167 168 //设置Sql语句169 var sql = "delete from <#=tbl.Name#> where <#=col.CleanName#> in (" + str + ")";170 171 //删除172 var deleteHelper = new DeleteHelper();173 deleteHelper.Delete(sql);174 }175 #endregion176 177 <#178 }179 //判断字段名称中是否包含“Name”这个字符串,且字段类型为string180 else if (col.CleanName.IndexOf("Name") >= 0 && col.SysType == "string") 181 {182 #>183 #region 获取<#=col.CleanName #>字段值184 ///
185 /// 获取<#=col.CleanName #>字段值186 /// 187 ///
主键Id188 ///
189 public string Get<#=col.CleanName #>(int pkValue)190 {191 //从数据库中查询192 var model = <#=tbl.Name#>.SingleOrDefault(x => x.Id == pkValue);193 return model == null ? "" : model.<#=col.CleanName #>; 194 }195 #endregion196 197 <#198 }199 //判断字段名称中是否包含“Img”这个字符串,且字段类型为string200 else if (col.CleanName.IndexOf("Img") >= 0 && col.SysType == "string") 201 {202 #>203 #region 删除<#=col.CleanName #>字段存储的对应图片204 ///
删除<#=col.CleanName #>字段存储的对应图片205 ///
主键Id206 public void Del<#=col.CleanName #>(int pkValue) 207 {208 try 209 {210 //添加删除语句211 }212 catch (Exception e) 213 {214 //出现异常,保存出错日志信息215 //添加保存出错日志语句216 }217 }218 #endregion219 220 <#221 222 }223 }224 #>225 }226 227 }228 229 230 <# 231 // 输出文件结束232 manager.EndBlock();233 } //if(!ExcludeTables.Contains(tbl.Name)) 判断结束234 235 }// end foreach236 237 // 执行编译,生成文件238 manager.Process(true); 239 #>

  运行模板,测试看看效果

  

  然后我们创建一个与模版中同名的类

  

  实现虚函数

  

  这样模板函数在执行相关操作时,如果我们重写了清空缓存这个函数,那么程序就会自动执行清空缓存函数了,而对于那些不需要该功能的类则没有任何影响

  这里要注意的是,我们的模板类与这个自定义类都有一个统一的修饰符partial

 

 

  大家先消化上面内容,才好理解下一章节中模板调用内容,下章会将写好的模板函数全部贴出来,让大家直接一步到位,生成Web层所需要的绝大部分调用函数,减少这一部分不必要的编码工作。

  

 

 

 下载地址:

 

 

 

 

 

 

 版权声明:

  本文由AllEmpty原创并发布于博客园,欢迎转载,未经本人同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。如有问题,可以通过1654937@qq.com 联系我,非常感谢。

 

  发表本编内容,只要主为了和大家共同学习共同进步,有兴趣的朋友可以加加Q群:327360708 ,大家一起探讨。

 

  更多内容,敬请观注博客:

 

 

 

 

 

转载于:https://www.cnblogs.com/EmptyFS/p/3738534.html

你可能感兴趣的文章
初识算法、数据结构
查看>>
QTP中对EXCEL进行读操作的格式
查看>>
Luogu4069 SDOI2016 游戏 树链剖分、李超线段树
查看>>
Java的内部类真的那么难以理解?
查看>>
一文搞懂Java环境,轻松实现Hello World!
查看>>
hash实现锚点平滑滚动定位
查看>>
也谈智能手机游戏开发中的分辨率自适应问题
查看>>
开始一个django项目
查看>>
重新学习angularjs--第一篇(入门)
查看>>
【转】MYSQL数据库设计规范与原则
查看>>
《中国大历史》—— 读后总结
查看>>
回溯法算法框架
查看>>
残差学习【转载】
查看>>
0302 关于IT行业的就业感想
查看>>
3、流程语句相关练习
查看>>
30、git 使用
查看>>
转发:China2008 标题:SharePoint 文档库打开HTML 直接浏览而不是打开下载对话框...
查看>>
iOS网络-02-数据解析(JSON与XML)
查看>>
python列表求和的几种等效电路
查看>>
Luogu P3393 逃离僵尸岛
查看>>