从零开始编写自己的C#框架(13)——T4模板在逻辑层中的应用(二)
最近这段时间特忙,公事私事,忙得有时都没时间打开电脑了,这两周只能尽量更新,以后再将章节补回来。
直接进入主题,通过上一章节,大家明白了怎么使用模板类编写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 /// <summary>
31 /// 获取本逻辑类单例
32 /// </summary>
33 /// <returns></returns>
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 #endregion
41
42 }
43
44 }
45
46
47 <#
48 // 输出文件结束
49 manager.EndBlock();
50 } //if(!ExcludeTables.Contains(tbl.Name)) 判断结束
51
52 }// end foreach
53
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 /// <summary>
33 /// 获取本逻辑类单例
34 /// </summary>
35 /// <returns></returns>
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 <#
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 /// <summary>
53 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录
54 /// </summary>
55 /// <param name="id">记录的主键值</param>
56 public void DeleteBy<#=col.CleanName#>(int id) {
57 //删除
58 <#=tbl.Name#>.Delete(x => x.<#=col.CleanName#> == id);
59 }
60
61 /// <summary>
62 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录
63 /// </summary>
64 /// <param name="id">记录的主键值</param>
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 #endregion
78
79 <#
80 }
81 }
82 #>
83 }
84
85 }
86
87
88 <#
89 // 输出文件结束
90 manager.EndBlock();
91 } //if(!ExcludeTables.Contains(tbl.Name)) 判断结束
92
93 }// end foreach
94
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 /// <summary>
33 /// 获取本逻辑类单例
34 /// </summary>
35 /// <returns></returns>
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 /// <summary>
52 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录
53 /// </summary>
54 /// <param name="id">记录的主键值</param>
55 public void DeleteBy<#=col.CleanName#>(int id) {
56 //删除
57 <#=tbl.Name#>.Delete(x => x.<#=col.CleanName#> == id);
58 }
59
60 /// <summary>
61 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录
62 /// </summary>
63 /// <param name="id">记录的主键值</param>
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 /// <summary>
86 /// 获取<#=col.CleanName #>字段值
87 /// </summary>
88 /// <param name="pkValue">主键Id</param>
89 /// <returns></returns>
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”这个字符串,且字段类型为string
101 else if (col.CleanName.IndexOf("Img") >= 0 && col.SysType == "string")
102 {
103 #>
104 #region 删除<#=col.CleanName #>字段存储的对应图片
105 /// <summary>删除<#=col.CleanName #>字段存储的对应图片</summary>
106 /// <param name="pkValue">主键Id</param>
107 public void Del<#=col.CleanName #>(int pkValue) {
108 try {
109 //添加删除语句
110 }
111 catch (Exception e) {
112 //出现异常,保存出错日志信息
113 //添加保存出错日志语句
114 }
115 }
116 #endregion
117
118 <#
119
120 }
121 }
122 #>
123 }
124
125 }
126
127
128 <#
129 // 输出文件结束
130 manager.EndBlock();
131 } //if(!ExcludeTables.Contains(tbl.Name)) 判断结束
132
133 }// end foreach
134
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 /// <summary>
36 /// 获取本逻辑类单例
37 /// </summary>
38 /// <returns></returns>
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 /// <summary>
51 /// 添加与编辑<#=tbl.Name#>记录
52 /// </summary>
53 /// <param name="model"><#=tbl.Name#>表实体</param>
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 /// <summary>
77 /// 删除<#=tbl.Name#>表记录
78 /// </summary>
79 /// <param name="id">记录的主键值</param>
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 /// <summary>
96 /// 删除<#=tbl.Name#>表记录
97 /// </summary>
98 /// <param name="id">记录的主键值</param>
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 /// <summary>
119 /// 获取数据表中的某个值——从数据库中查询,如果使用了缓存,删除成功后会清空本表的所有缓存记录,然后重新加载进缓存
120 /// </summary>
121 /// <param name="expression">条件语句</param>
122 /// <returns></returns>
123 public void Delete(Expression<Func<<#=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 #endregion
135
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 /// <summary>
149 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录
150 /// </summary>
151 /// <param name="id">记录的主键值</param>
152 public void DeleteBy<#=col.CleanName#>(int id)
153 {
154 //删除
155 <#=tbl.Name#>.Delete(x => x.<#=col.CleanName#> == id);
156 }
157
158 /// <summary>
159 /// 删除<#=tbl.Name#>表指定<#=col.CleanName#>的字段值记录
160 /// </summary>
161 /// <param name="id">记录的主键值</param>
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 #endregion
176
177 <#
178 }
179 //判断字段名称中是否包含“Name”这个字符串,且字段类型为string
180 else if (col.CleanName.IndexOf("Name") >= 0 && col.SysType == "string")
181 {
182 #>
183 #region 获取<#=col.CleanName #>字段值
184 /// <summary>
185 /// 获取<#=col.CleanName #>字段值
186 /// </summary>
187 /// <param name="pkValue">主键Id</param>
188 /// <returns></returns>
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 #endregion
196
197 <#
198 }
199 //判断字段名称中是否包含“Img”这个字符串,且字段类型为string
200 else if (col.CleanName.IndexOf("Img") >= 0 && col.SysType == "string")
201 {
202 #>
203 #region 删除<#=col.CleanName #>字段存储的对应图片
204 /// <summary>删除<#=col.CleanName #>字段存储的对应图片</summary>
205 /// <param name="pkValue">主键Id</param>
206 public void Del<#=col.CleanName #>(int pkValue)
207 {
208 try
209 {
210 //添加删除语句
211 }
212 catch (Exception e)
213 {
214 //出现异常,保存出错日志信息
215 //添加保存出错日志语句
216 }
217 }
218 #endregion
219
220 <#
221
222 }
223 }
224 #>
225 }
226
227 }
228
229
230 <#
231 // 输出文件结束
232 manager.EndBlock();
233 } //if(!ExcludeTables.Contains(tbl.Name)) 判断结束
234
235 }// end foreach
236
237 // 执行编译,生成文件
238 manager.Process(true);
239 #>
运行模板,测试看看效果
然后我们创建一个与模版中同名的类
实现虚函数
这样模板函数在执行相关操作时,如果我们重写了清空缓存这个函数,那么程序就会自动执行清空缓存函数了,而对于那些不需要该功能的类则没有任何影响
这里要注意的是,我们的模板类与这个自定义类都有一个统一的修饰符partial
大家先消化上面内容,才好理解下一章节中模板调用内容,下章会将写好的模板函数全部贴出来,让大家直接一步到位,生成Web层所需要的绝大部分调用函数,减少这一部分不必要的编码工作。
下载地址:
版权声明:
本文由AllEmpty原创并发布于博客园,欢迎转载,未经本人同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。如有问题,可以通过1654937@qq.com 联系我,非常感谢。
发表本编内容,只要主为了和大家共同学习共同进步,有兴趣的朋友可以加加Q群:327360708 ,大家一起探讨。
更多内容,敬请观注博客:http://www.cnblogs.com/EmptyFS/