從零開始編寫自己的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層所需要的絕大部分調用函數,減少這一部分不必要的編碼工作。

  

 

 

 下載地址:

T4模板在邏輯層中的應用(二).rar 

 

 

 

 

 

 版權聲明:

  本文由AllEmpty原創並發布於博客園,歡迎轉載,未經本人同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,否則保留追究法律責任的權利。如有問題,可以通過1654937@qq.com 聯系我,非常感謝。

 

  發表本編內容,只要主為了和大家共同學習共同進步,有興趣的朋友可以加加Q群:327360708 ,大家一起探討。

 

  更多內容,敬請觀注博客:http://www.cnblogs.com/EmptyFS/

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM