最近學習使用CodeSmith代碼生成器
CodeSmith 是一種語法類似於asp.net的基於模板的代碼生成器,程序可以自定義模板,從而減少重復編碼的勞動量,提高效率。
作用:CodeSmith 是一種基於模板的代碼生成工具,它使用類似於ASP.NET的語法來生成任意類型的代碼或文本。與其他許多代碼生成工具不同,CodeSmith 不要求您訂閱特定的應用程序設計或體系結構。使用 CodeSmith,可以生成包括簡單的強類型集合和完整應用程序在內的任何東西。
當您生成應用程序時,您經常需要重復完成某些特定的任務,例如編寫數據訪問代碼或者生成自定義集合。CodeSmith 在這些時候特別有用,因為您可以編寫模板自動完成這些任務,從而不僅提高您的工作效率,而且能夠自動完成那些最為乏味的任務。CodeSmith 附帶了許多模板,包括對應於所有 .NET 集合類型的模板以及用於生成存儲過程的模板,但該工具的真正威力在於能夠創建自定義模板。
應用:CodeSmith 是一種語法類似於asp.net的基於模板的代碼生成器,程序可以自定義模板,從而減少重復編碼的勞動量,提高效率。
安裝CodeSmith 2.6注冊後發現有兩個可運行程序CodeSmith Studio.exe和CodeSmith Explorer.exe
CodeSmith Studio.exe用來創建自定義模板
CodeSmith Explorer.exe用來導入模板並且生成代碼
打開 CodeSmith Studio.exe,新建一個C#模板。發現有如下類似與asp.net的標識符號
<% %>
<%= %>
<%@ %>
<script runat="template"> </script>
官方站點:http://www.codesmithtools.com/
下面是使用CodeSmith常用的方法
1 using System; 2 using SchemaExplorer; 3 using System.Data; 4 using CodeSmith.Engine; 5 using System.Text.RegularExpressions; 6 7 /// <summary> 8 /// CodeSmith公用方法類 9 /// </summary> 10 public class ToolsCodeTemplate:CodeTemplate 11 { 12 #region 獲取Molde類名稱 13 /// <summary> 14 /// 獲取Molde類名稱 15 /// </summary> 16 /// <param name="table">表</param> 17 /// <returns>表名稱(表名稱即為Model類名稱)</returns> 18 public string GetModelClassName(TableSchema table) 19 { 20 string result; 21 if ( table.ExtendedProperties.Contains("ModelName") ) 22 { 23 result = (string)table.ExtendedProperties["ModelName"].Value; 24 return MakePascal(result); 25 } 26 27 if (table.Name.EndsWith("s")) 28 { 29 result = MakeSingle(table.Name); 30 } 31 else 32 { 33 result = table.Name; 34 } 35 36 return MakePascal(result); 37 } 38 #endregion 39 40 #region 獲取屬性名稱 41 /// <summary> 42 /// 獲取屬性名稱 43 /// </summary> 44 /// <param name="column"></param> 45 /// <returns></returns> 46 public string GetPropertyName(ColumnSchema column) 47 { 48 return MakePascal(GetNameFromDBFieldName(column)); 49 } 50 #endregion 51 52 #region 獲取從數據庫字段得到的名稱 53 /// <summary> 54 /// 獲取從數據庫字段得到的名稱 55 /// </summary> 56 /// <param name="column"></param> 57 /// <returns></returns> 58 public string GetNameFromDBFieldName(ColumnSchema column) 59 { 60 return column.Name; 61 } 62 #endregion 63 64 #region 獲取屬性類型 65 /// <summary> 66 /// 獲取屬性類型 67 /// </summary> 68 /// <param name="column">列</param> 69 /// <returns>屬性類型</returns> 70 public string GetPropertyType(ColumnSchema column) 71 { 72 return GetCSharpTypeFromDBFieldType(column); 73 } 74 #endregion 75 76 #region 獲取主鍵名稱 77 /// <summary> 78 /// 獲取主鍵名稱 79 /// </summary> 80 /// <param name="TargetTable">表</param> 81 /// <returns>主鍵名稱</returns> 82 public string GetPKName(TableSchema TargetTable) 83 { 84 if (TargetTable.PrimaryKey != null) 85 { 86 if (TargetTable.PrimaryKey.MemberColumns.Count == 1) 87 { 88 return TargetTable.PrimaryKey.MemberColumns[0].Name; 89 } 90 else 91 { 92 throw new Exception("This template will not work on primary keys with more than one member column."); 93 } 94 } 95 else 96 { 97 throw new Exception("This template will only work on tables with a primary key."); 98 } 99 } 100 #endregion 101 102 #region 獲取主鍵類型 103 /// <summary> 104 /// 獲取主鍵類型 105 /// </summary> 106 /// <param name="TargetTable">表</param> 107 /// <returns>主鍵類型</returns> 108 public string GetPKType(TableSchema TargetTable) 109 { 110 if (TargetTable.PrimaryKey != null) 111 { 112 if (TargetTable.PrimaryKey.MemberColumns.Count == 1) 113 { 114 return GetCSharpTypeFromDBFieldType(TargetTable.PrimaryKey.MemberColumns[0]); 115 } 116 else 117 { 118 throw new ApplicationException("This template will not work on primary keys with more than one member column."); 119 } 120 } 121 else 122 { 123 throw new ApplicationException("This template will only work on MyTables with a primary key."); 124 } 125 } 126 #endregion 127 128 #region 類型轉化 129 /// <summary> 130 /// 獲取數據庫類型轉化為C#類型 131 /// </summary> 132 /// <param name="column">列</param> 133 /// <returns>C#類型的字符串</returns> 134 public string GetCSharpTypeFromDBFieldType(ColumnSchema column) 135 { 136 if (column.Name.EndsWith("TypeCode")) return column.Name; 137 string type; 138 switch (column.DataType) 139 { 140 case DbType.AnsiString: type= "string";break; 141 case DbType.AnsiStringFixedLength: type= "string";break; 142 case DbType.Binary: type= "byte[]";break; 143 case DbType.Boolean: type= "bool";break; 144 case DbType.Byte: type= "byte";break; 145 case DbType.Currency: type= "decimal";break; 146 case DbType.Date: type= "DateTime";break; 147 case DbType.DateTime: type= "DateTime";break; 148 case DbType.Decimal: type= "decimal";break; 149 case DbType.Double: type= "double";break; 150 case DbType.Guid: type= "Guid";break; 151 case DbType.Int16: type= "short";break; 152 case DbType.Int32: type= "int";break; 153 case DbType.Int64: type= "long";break; 154 case DbType.Object: type= "object";break; 155 case DbType.SByte: type= "sbyte";break; 156 case DbType.Single: type= "float";break; 157 case DbType.String: type= "string";break; 158 case DbType.StringFixedLength: type= "string";break; 159 case DbType.Time: type= "TimeSpan";break; 160 case DbType.UInt16: type= "ushort";break; 161 case DbType.UInt32: type= "uint";break; 162 case DbType.UInt64: type= "ulong";break; 163 case DbType.VarNumeric: type= "decimal";break; 164 default: 165 { 166 type= "__UNKNOWN__" + column.NativeType;//未知 167 break; 168 } 169 } 170 //是否為Null 171 if(column.AllowDBNull && column.SystemType.IsValueType) 172 { 173 type=type+"?"; 174 } 175 return type; 176 } 177 /// <summary> 178 /// 獲取數據庫類型轉化為C#類型 179 /// </summary> 180 /// <param name="dbType">DbType的類型</param> 181 /// <returns>C#類型的字符串</returns> 182 public string GetDBTypeToCSharpType (System.Data.DbType dbType) 183 { 184 switch (dbType) 185 { 186 case DbType.AnsiString:return "string"; 187 case DbType.AnsiStringFixedLength:return "string"; 188 case DbType.Binary:return "byte[]"; 189 case DbType.Boolean:return "bool"; 190 case DbType.Byte:return "byte"; 191 case DbType.Currency:return "decimal"; 192 case DbType.Date:return "DateTime"; 193 case DbType.DateTime:return "DateTime"; 194 case DbType.DateTime2:return "DateTime"; 195 case DbType.DateTimeOffset:return "DateTime"; 196 case DbType.Decimal:return "decimal"; 197 case DbType.Double:return "double"; 198 case DbType.Guid:return "Guid"; 199 case DbType.Int16:return "short"; 200 case DbType.Int32:return "int"; 201 case DbType.Int64:return "long"; 202 case DbType.Object:return "object"; 203 case DbType.SByte:return "sbyte"; 204 case DbType.Single:return "float"; 205 case DbType.String:return "string"; 206 case DbType.StringFixedLength:return "string"; 207 case DbType.Time:return "DateTime"; 208 case DbType.UInt16:return "ushort"; 209 case DbType.UInt32:return "uint"; 210 case DbType.UInt64:return "ulong"; 211 case DbType.VarNumeric:return "decimal"; 212 case DbType.Xml:return "string"; 213 default:return "object"; 214 } 215 } 216 #endregion 217 218 #region 駱駝命名法,帕斯卡命名法和匈牙利命名法 219 /// <summary> 220 /// 獲取首字母大寫的字符串 221 /// </summary> 222 /// <param name="value">字符串(例如:xiangyisheng)</param> 223 /// <returns>xiangyisheng => Xiangyisheng</returns> 224 public string MakePascal(string value) 225 { 226 return value.Substring(0, 1).ToUpper() + value.Substring(1); 227 } 228 /// <summary> 229 /// 獲取首字母小寫的字符串 230 /// </summary> 231 /// <param name="value">字符串(例如:Xiangyisheng)</param> 232 /// <returns>Xiangyisheng => xiangyisheng</returns> 233 public string MakeCamel(string value) 234 { 235 return value.Substring(0, 1).ToLower() + value.Substring(1); 236 } 237 /// <summary> 238 /// 獲取小寫的字符串 239 /// </summary> 240 /// <param name="value">字符串(例如:XiangYiSheng)</param> 241 /// <returns>XiangYiSheng => xiangyisheng</returns> 242 public string MakeSmall(string value) 243 { 244 return value.ToLower(); 245 } 246 /// <summary> 247 /// 獲取單數形式的字符串 248 /// </summary> 249 /// <param name="name">字符串(例如:Xiangyishengs)</param> 250 /// <returns>Xiangyishengs => Xiangyisheng</returns> 251 public string MakeSingle(string name) 252 { 253 Regex plural1 = new Regex("(?<keep>[^aeiou])ies$"); 254 Regex plural2 = new Regex("(?<keep>[aeiou]y)s$"); 255 Regex plural3 = new Regex("(?<keep>[sxzh])es$"); 256 Regex plural4 = new Regex("(?<keep>[^sxzhyu])s$"); 257 258 if(plural1.IsMatch(name)) 259 return plural1.Replace(name, "${keep}y"); 260 else if(plural2.IsMatch(name)) 261 return plural2.Replace(name, "${keep}"); 262 else if(plural3.IsMatch(name)) 263 return plural3.Replace(name, "${keep}"); 264 else if(plural4.IsMatch(name)) 265 return plural4.Replace(name, "${keep}"); 266 267 return name; 268 } 269 /// <summary> 270 /// 獲取復數形式的字符串 271 /// </summary> 272 /// <param name="name">字符串(例如:Xiangyisheng)</param> 273 /// <returns>Xiangyisheng => Xiangyishengs</returns> 274 public string MakePlural(string name) 275 { 276 Regex plural1 = new Regex("(?<keep>[^aeiou])y$"); 277 Regex plural2 = new Regex("(?<keep>[aeiou]y)$"); 278 Regex plural3 = new Regex("(?<keep>[sxzh])$"); 279 Regex plural4 = new Regex("(?<keep>[^sxzhy])$"); 280 281 if(plural1.IsMatch(name)) 282 return plural1.Replace(name, "${keep}ies"); 283 else if(plural2.IsMatch(name)) 284 return plural2.Replace(name, "${keep}s"); 285 else if(plural3.IsMatch(name)) 286 return plural3.Replace(name, "${keep}es"); 287 else if(plural4.IsMatch(name)) 288 return plural4.Replace(name, "${keep}s"); 289 290 return name; 291 } 292 #endregion 293 294 #region 打印標題 295 /// <summary> 296 /// 打印標題 297 /// </summary> 298 public void PrintHeader() 299 { 300 Response.WriteLine("//============================================================"); 301 Response.WriteLine("//http://www.cnblogs.com/xiangyisheng"); 302 Response.WriteLine("//============================================================"); 303 Response.WriteLine(); 304 } 305 #endregion 306 } ToolsCodeTemplate下面是我理解ToolsCodeTemplate測試例子
1 <%-- 2 名稱:測試模板 3 作者:長毛象 4 描述:測試模板 5 網址:http://www.cnblogs.com/xiangyisheng 6 --%> 7 <%@ CodeTemplate Language="C#" TargetLanguage="text" Src="ToolsCodeTemplate.cs" Inherits="ToolsCodeTemplate" Debug="False" Description="測試模板" ResponseEncoding="UTF-8" %> 8 <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Default="" Optional="False" Category="Table" Description="源表名" OnChanged="" Editor="" EditorBase="" Serializer="" %> 9 <%@ Assembly Name="SchemaExplorer" %> 10 <%@ Import Namespace="SchemaExplorer" %> 11 <%@ Import Namespace="System.Data" %> 12 <% PrintHeader(); %> 13 14 <%--獲取Molde類名稱 參數:表--%> 15 獲取Molde類名稱:<%= this.GetModelClassName(this.SourceTable) %> 16 17 <%--獲取屬性名稱 參數:列--%> 18 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 19 獲取屬性名稱:<%=this.GetPropertyName(column)%> 20 <%}%> 21 22 <%--獲取從數據庫字段得到的名稱 參數:列--%> 23 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 24 獲取從數據庫字段得到的名稱:<%=this.GetNameFromDBFieldName(column)%> 25 <%}%> 26 27 <%--獲取屬性類型 參數:列--%> 28 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 29 獲取屬性類型:<%=this.GetPropertyType(column)%> 30 <%}%> 31 32 <%--獲取主鍵名稱 參數:表--%> 33 獲取主鍵名稱:<%= this.GetPKName(this.SourceTable) %> 34 35 <%--獲取主鍵類型 參數:表--%> 36 獲取主鍵類型:<%= this.GetPKType(this.SourceTable) %> 37 38 <%--獲取數據庫類型轉化為C#類型 參數:列--%> 39 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 40 獲取數據庫類型轉化為C#類型:<%=this.GetCSharpTypeFromDBFieldType(column)%> 41 <%}%> 42 43 <%--獲取數據庫類型轉化為C#類型2 參數:列類型--%> 44 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 45 獲取數據庫類型轉化為C#類型2:<%=this.GetDBTypeToCSharpType(column.DataType)%> 46 <%}%> 47 48 <%--獲取首字母大寫的字符串 參數:字符串--%> 49 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 50 獲取首字母大寫的字符串:<%=this.MakePascal(column.Name)%> 51 <%}%> 52 53 <%--獲取首字母小寫的字符串 參數:字符串--%> 54 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 55 獲取首字母小寫的字符串:<%=this.MakeCamel(column.Name)%> 56 <%}%> 57 58 <%--獲取小寫的字符串 參數:字符串--%> 59 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 60 獲取小寫的字符串:<%=this.MakeSmall(column.Name)%> 61 <%}%> 62 63 <%--獲取單數形式的字符串 參數:字符串--%> 64 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 65 獲取單數形式的字符串:<%=this.MakeSingle(column.Name)%> 66 <%}%> 67 68 <%--獲取復數形式的字符串 參數:字符串--%> 69 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 70 獲取首字母大寫的字符串:<%=this.MakePascal(column.Name)%> 71 <%}%> TestTemplate創建生成實體類的模板,代碼如下:
1 <%-- 2 Name:實體類 3 Author: Eason.Xiang 4 Description: 5 --%> 6 <%@ CodeTemplate Language="C#" TargetLanguage="C#" Src="ToolsCodeTemplate.cs" Inherits="ToolsCodeTemplate" Debug="False" Description="生成指定Table的實體類(使用原始方式封裝字段(Ctrl+R+E))" ResponseEncoding="UTF-8" %> 7 <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Default="" Optional="False" Category="Table" Description="源表名" OnChanged="" Editor="" EditorBase="" Serializer="" %> 8 <%@ Property Name="NameSpace" Type="System.String" Default="Model" Optional="False" Category="NameSpace" Description="命名空間" OnChanged="" Editor="" EditorBase="" Serializer="" %> 9 <%@ Property Name="IsFK" Type="System.Boolean" Default="False" Optional="False" Category="Other" Description="是否處理外鍵" OnChanged="" Editor="" EditorBase="" Serializer="" %> 10 <%@ Property Name="Author" Type="System.String" Default="Jack.Zhou" Optional="False" Category="Other" Description="" OnChanged="" Editor="" EditorBase="" Serializer="" %> 11 <%@ Assembly Name="SchemaExplorer" %> 12 <%@ Assembly Name="System.Data" %> 13 <%@ Assembly Name="mscorlib" %> 14 <%@ Import Namespace="SchemaExplorer" %> 15 <%@ Import Namespace="System.Data" %> 16 <%@ Import Namespace="System.Collections.Generic" %> 17 <% PrintHeader(); %> 18 using System; 19 using System.Collections.Generic; 20 using System.Text; 21 namespace <%=this.NameSpace%> 22 { 23 /// <summary> 24 /// 實體類<%=this.GetModelClassName(this.SourceTable)%> 25 /// </summary> 26 public class <%=this.GetModelClassName(this.SourceTable)%> 27 { 28 #region 私有字段 29 <%foreach(ColumnSchema column in this.SourceTable.ForeignKeyColumns){%> 30 <%if(!IsFK){%> 31 private <%=this.GetCSharpTypeFromDBFieldType(column)%> _<%=this.MakeCamel(column.Name)%>; 32 <%}else{%> 33 private <%=this.GetFKClassName(column)%> _<%=this.MakeCamel(column.Name)%>; 34 <%}%> 35 <%}%> 36 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 37 private <%=this.GetCSharpTypeFromDBFieldType(column)%> _<%=this.MakeCamel(column.Name)%>; 38 <%}%> 39 #endregion 40 41 #region 公開屬性 42 <%foreach(ColumnSchema column in this.SourceTable.ForeignKeyColumns){%> 43 <%if(!IsFK){%> 44 public <%=this.GetCSharpTypeFromDBFieldType(column)%> <%=this.MakePascal(column.Name)%> 45 { 46 get{return _<%=this.MakeCamel(column.Name)%>;} 47 set{_<%=this.MakeCamel(column.Name)%>=value;} 48 } 49 <%}else{%> 50 public <%=this.GetFKClassName(column)%> <%=this.MakePascal(column.Name)%> 51 { 52 get{return _<%=this.MakeCamel(column.Name)%>;} 53 set{_<%=this.MakeCamel(column.Name)%>=value;} 54 } 55 <%}%> 56 <%}%> 57 <%foreach(ColumnSchema column in this.SourceTable.NonForeignKeyColumns){%> 58 public <%=this.GetCSharpTypeFromDBFieldType(column)%> <%=this.MakePascal(column.Name)%> 59 { 60 get{return _<%=this.MakeCamel(column.Name)%>;} 61 set{_<%=this.MakeCamel(column.Name)%>=value;} 62 } 63 <%}%> 64 #endregion 65 } 66 } 67 <script runat="template"> 68 #region 獲取外鍵類名 69 public string GetFKClassName(ColumnSchema column) 70 { 71 foreach(TableKeySchema key in this.SourceTable.ForeignKeys) 72 { 73 foreach(MemberColumnSchema fk in key.ForeignKeyMemberColumns) 74 { 75 if(fk.Name==column.Name) 76 { 77 return this.GetModelClassName(key.PrimaryKeyTable); 78 } 79 } 80 } 81 return ""; 82 } 83 #endregion 84 </script> TableEntityCodeSmith截圖
好了,目前大概就學到這裡了。(原文:http://www.cnblogs.com/xiangyisheng/p/6208637.html)