最近這段時間特忙,公事私事,忙得有時都沒時間打開電腦了,這兩周隻能盡量更新,以後再将章節補回來。
直接進入主題,通過上一章節,大家明白了怎麼使用模闆類編寫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層所需要的絕大部分調用函數,減少這一部分不必要的編碼工作。
下載下傳位址:
T4模闆在邏輯層中的應用(二).rar
版權聲明:
本文由AllEmpty原創并釋出于部落格園,歡迎轉載,未經本人同意必須保留此段聲明,且在文章頁面明顯位置給出原文連結,否則保留追究法律責任的權利。如有問題,可以通過[email protected] 聯系我,非常感謝。
發表本編内容,隻要主為了和大家共同學習共同進步,有興趣的朋友可以加加Q群:327360708 ,大家一起探讨。
更多内容,敬請觀注部落格:http://www.cnblogs.com/EmptyFS/
隻有将自己置空,才能裝進更多的東西!我是陳煥,資深IT碼農,愛分享愛學習,一位奔跑在求知路上的踐行者。