CodeSmith 基础用法和例子
〇、??????????? 前言
一、??????????? 工具設置
CodeSmith默認是不支持中文的,那么我們必須要先設置使其支持中文顯示,保存。并且要能夠在生成文件中支持中文。
<%@ CodeTemplate TargetLanguage="Text" Src="" Inherits="" Debug="False" CompilerVersion="v3.5" Description="Template description here." %>
中加入ResponseEncoding="UTF-8" 的標簽。將會使得生成的文件也支持中文。
?
二、??????????? 模板區域說明
CodeSmith的模板分為六個區域:模板說明區域,屬性設置區域,注冊模板區域,引用聲明區域,模板區域,函數區域。
(一)??????? 模板說明區域,只有一句話:
<%@ CodeTemplate ResponseEncoding="UTF-8" TargetLanguage="Text" Src="" Inherits="" Debug="False" CompilerVersion="v3.5" Description="這里是模板說明" %>
(二)??????? 屬性設置區域
你模板需要那些外接參數,都可以寫在這里。當然還有一些其他的參數需要些在函數區域,在后面我們再來描述。
1)?? String類型參數聲明:
<%@ Property Default="AAA" Optional="True" Category="輸入參數" Description="這是一個字符串型的參數" %>
2)?? Bool類型參數聲明:
<%@ Property Default="True" Optional="False" Category="輸入參數" Description="這是一個布朗型的參數" %>
3)?? DatabaseSchema類型參數聲明:
<%@ Property Category="Context" Description="這是一個數據庫" %>
4)?? TableSchemaCollection類型參數聲明:
<%@ Property Category="Context" Description="這是一個數據表集合" %>
5)?? TableSchema類型參數聲明:
<%@ Property Category="Context" Description="這是一個數據表" %>
(三)??????? 注冊模板區域
在你的模板中可以調用其他的模板用于生成,當然,你調用的模板所需要的參數你都必須給出。注冊代碼如下:
<%@ Register Template="B.cst" MergeProperties="False" ExcludeProperties="" %>
這就是將B模板注冊到A模板中。
(四)??????? 引用聲明區域
在這里要將我們使用到了的應用集都在這里寫出來,如果使用到數據庫就一定要添加下面的兩個。
<%@ Assembly %>
<%@ Import Namespace="SchemaExplorer" %>
要自己控制輸出文件的話就需要添加:<%@ Import Namespace="System.IO"?%>
(五)??????? 模板區域
這里就是我們控制要輸出的文件或者界面的內容。
直接輸出值為<%= ThisIsString %>
調用代碼為<% if (ThisIsBool) { %>A<% } %>?如果ThisIsBool為true則輸出A。
(六)??????? 函數區域
在這里我們可以定義我們自己的函數,用于一些復雜的組合、代碼的重用等。代碼格式和C#完全一樣。
?
三、??????????? 模板編寫方法
A.???? 直接輸出
在模板區域直接輸入文本,就會直接輸出的output里面了。
?
B.???? 變量輸出
例如輸出ThisIsString的變量值:<%= ThisIsString %>
再例如輸出ThisIsTable的名字:<%=?ThisIsTable.Name %>
?
C.????? 調用函數
例如,如果輸入的ThisIsBool為true就輸出A字符。
<% if (ThisIsBool) { %>A<% } %>
?
?
D.??? 調用模板
這里我們將在A模板內調用并顯示B模板。每個模板都有一個Response來存儲模板輸出的。模板顯示是調用Render()方法來完成的。
<% for(int i = 0; i < ThisIsTableList.Count; i++)
{
??? B b = new B();
??? b.ThisIsTable = ThisIsTableList[i];
??? b.Render(this.Response);
} %>
?
E.????? 遍歷Database或TableCollection內的表
這里我們可以使用for或者foreach做循環,為了通用性例子全部使用for做循環。
遍歷ThisIsDatabase并輸出表名
<% for (int t = 0; t < ThisIsDatabase.Tables.Count; t++) { %>
??? <%= ThisIsDatabase.Tables[t].Name %>
<% } %>
?
F.????? 遍歷Table的列
遍歷ThisIsTable的列并且生成類似如下格式的語句:
//數據庫類型:DbType.int
private int _ID;
這里調用了一個方法DataType2CSharpType(System.Data.DbType dbType)在后面將會講到。
<% for (int c = 0; c < ThisIsTable.Columns.Count; c++) { %>
??? //數據庫類型:DbType.<%= DataType2CSharpType(ThisIsTable.Columns[c].DataType) %>
??? private <%= DataType2CSharpType(ThisIsTable.Columns[c].DataType) %> _<%= ThisIsTable.Columns[c].Name %>;
???
<% } %>
?輸出結果:
??? //數據庫類型:DbType.int
??? private int _ID;
???
??? //數據庫類型:DbType.int
??? private int _ClassID;
???
??? //數據庫類型:DbType.string
??? private string _StudentName;
?
G.???? 遍歷Table的PK
<% for (int c = 0; c < ThisIsTable.PrimaryKey.MemberColumns.Count; c++) { %>
主鍵<%= c %>:<%= ThisIsTable.PrimaryKey.Name %>
??? <%= ThisIsTable.PrimaryKey.Table.Name %>.<%= ThisIsTable.PrimaryKey.MemberColumns[c].Name %>
<% } %>
輸出結果?:
主鍵0:PK_Student
??? Student.ID
?
H.??? 遍歷Table的FK(Table自己是外鍵表<即Table為明細表>)
這里說明下,下面的代碼僅僅只是對FK里面的列是一對一的有效,如果是多對多的FK需要修改下面的0的地方為循環即可。
<% for (int c = 0; c < ThisIsTable.ForeignKeys.Count; c++) { %>
外鍵<%= c %>:<%= ThisIsTable.ForeignKeys[c].Name %>
??? 外鍵<%= c %>對應的列
??? <% for (int i = 0; i < ThisIsTable.ForeignKeys[c].PrimaryKeyMemberColumns.Count; i++) { %>
??????? <%= ThisIsTable.ForeignKeys[c].ForeignKeyTable.Name %>.<%= ThisIsTable.ForeignKeys[c].ForeignKeyMemberColumns[0].Name %> <——來自于 <%= ThisIsTable.ForeignKeys[c].PrimaryKeyTable.Name %>.<%= ThisIsTable.ForeignKeys[c].PrimaryKeyMemberColumns[0].Name %>
??? <% } %>
<% } %>
?輸出結果:
外鍵0:FK_Student_Class
??? 外鍵0對應的列
?
I.??????? 遍歷Table的FK(Table自己是主鍵表<即Table為父表>)
<% for (int c = 0; c < ThisIsTable.PrimaryKeys.Count; c++) { %>
其他表外鍵<%= c %>:<%= ThisIsTable.PrimaryKeys[c].Name %>
??? 其他表外鍵<%= c %>對應的列:
??? <% for (int i = 0; i < ThisIsTable.PrimaryKeys[c].PrimaryKeyMemberColumns.Count; i++) { %>
??????? <%= ThisIsTable.PrimaryKeys[c].PrimaryKeyTable.Name %>.<%= ThisIsTable.PrimaryKeys[c].PrimaryKeyMemberColumns[0].Name %> 作用于——> <%= ThisIsTable.PrimaryKeys[c].ForeignKeyTable.Name %>.<%= ThisIsTable.PrimaryKeys[c].ForeignKeyMemberColumns[0].Name %>
??? <% } %>
<% } %>
輸出結果:
其他表外鍵0:FK_ExamScore_Student
??? 其他表外鍵0對應的列:
??????? Student.ID 作用于——> ExamScore.StudentID
四、??????????? 函數區域用法
之前我們提到過,有些參數必須要寫在函數區域中。當然這些參數就是需要有一些其他組件支持的參數了,比如彈出一個窗口選擇文件,或者彈出一個選擇文件夾的窗體,用于輸入的參數。
1)??? 添加一個選擇目錄的輸入參數
下面我們就是定義了一個輸入參數OutputDirectory,在運行的輸入參數界面,點擊這個參數的輸入框就會彈出一個選擇目錄的窗口。
??? private string templateOutputDirectory = "";
???
??? [Editor(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
??? [Optional, NotChecked]
??? [Category("OutputInfo")]
??? [Description("輸出結果的目錄。")]
??? [DefaultValue("")]
??? public string OutputDirectory
??? {
??????? get
??????? {
??????????? if (string.IsNullOrEmpty(templateOutputDirectory))
??????????? {
??????????????? return "C:\\"+ (ThisIsDatabase!= null ? ThisIsDatabase.Name : "Output");
??????????? }
??????????? else
??????????? {
??????????????? return templateOutputDirectory;
??????????? }
??????? }
??????? set
??????? {
??????????? if (value.EndsWith("\\")) value = value.Substring(0, value.Length - 1);
??????????? templateOutputDirectory = value;
??????? }
??? }
?
2)??? 添加一個選擇文件的輸入參數
下面我們就是定義了一個輸入參數OutputFile,在運行的輸入參數界面,點擊這個參數的輸入框就會彈出一個選擇文件的窗口。
????private?string templateOutputFile;
???
??? [Editor(typeof(System.Windows.Forms.Design.FileNameEditor), typeof(System.Drawing.Design.UITypeEditor))] ??
??? [Optional, NotChecked]
??? [Category("OutputInfo")]
??? [Description("輸出文件")]
??? [DefaultValue("")]
??? public string OutputFile
??? {
??????? get
??????? {
??????????? if (string.IsNullOrEmpty(templateOutputFile))
??????????? {
??????????????? return "C:\\"+ (ThisIsDatabase != null ? ThisIsDatabase.Name + ".cs" : "Output.cs");
??????????? }
??????????? else
??????????? {
??????????????? return templateOutputFile;
??????????? }
??????? }
??????? set
??????? {
??????????? templateOutputFile = value;
??????? }
??? }
?
3)??? 將數據庫類型轉化為C#類型的函數
輸入DbType的類型轉化后輸出C#的類型的字符串。這個函數很常用到。
????public string?DataType2CSharpType(System.Data.DbType dbType)
??? {
??????? switch (dbType)
??????? {
??????????? case DbType.AnsiString:
??????????????? return "string";
??????????? case DbType.AnsiStringFixedLength:
??????????????? return "string";
??????????? case DbType.Binary:
??????????????? return "byte[]";
??????????? case DbType.Boolean:
??????????????? return "bool";
??????????? case DbType.Byte:
??????????????? return "byte";
??????????? case DbType.Currency:
??????????????? return "decimal";
??????????? case DbType.Date:
??????????????? return "DateTime";
??????????? case DbType.DateTime:
??????????????? return "DateTime";
??????????? case DbType.DateTime2:
??????????????? return "DateTime";
??????????? case DbType.DateTimeOffset:
??????????????? return "DateTime";
??????????? case DbType.Decimal:
??????????????? return "decimal";
??????????? case DbType.Double:
??????????????? return "double";
??????????? case DbType.Guid:
??????????????? return "Guid";
??????????? case DbType.Int16:
??????????????? return "short";
??????????? case DbType.Int32:
??????????????? return "int";
??????????? case DbType.Int64:
??????????????? return "long";
??????????? case DbType.Object:
??????????????? return "object";
??????????? case DbType.SByte:
??????????????? return "sbyte";
??????????? case DbType.Single:
??????????????? return "float";
??????????? case DbType.String:
??????????? ??? return "string";
??????????? case DbType.StringFixedLength:
??????????????? return "string";
??????????? case DbType.Time:
??????????????? return "DateTime";
???????????????
??????????? case DbType.UInt16:
??????????????? return "ushort";
??????????? case DbType.UInt32:
??????????????? return "uint";
??????????? case DbType.UInt64:
??????????????? return "ulong";
??????????? case DbType.VarNumeric:
??????????????? return "decimal";
??????????? case DbType.Xml:
??????????????? return "string";
??????????? default:
??????????????? return "object";
??????? }
??? }
?
?
4)??? 獲取數據庫類型的字段在C#中的默認值
輸入DbType的類型轉化后輸出C#的類型的默認值。這個函數和上面那個差不多,只是有些時候設置了值后希望給個默認值而已。
????public?string DataTypeDefaultValue(System.Data.DbType dbType)
??? {
??????? switch (dbType)
??????? {
??????????? case DbType.AnsiString:
??????????????? return "String.Empty";
??????????? case DbType.AnsiStringFixedLength:
??????????????? return "String.Empty";
??????????? case DbType.Binary: //Answer modified was just 0
??????????????? return "new byte[] {}";
??????????? case DbType.Boolean:
??????????????? return "false";
??????????? case DbType.Byte: //Answer modified was just 0
??????????????? return "(byte)0";
??????????? case DbType.Currency:
??????????????? return "0";
??????????? case DbType.Date:
??????????????? return "DateTime.MinValue";
??????????? case DbType.DateTime:
??????????????? return "DateTime.MinValue";
??????????? case DbType.DateTime2:
??????????????? return "DateTime.MinValue";
??????????? case DbType.DateTimeOffset:
??????????????? return "DateTime.MinValue";
??????????? case DbType.Decimal:
??????????????? return "0.0m";
??????????? case DbType.Double:
??????????????? return "0.0f";
??????????? case DbType.Guid:
??????????????? return "Guid.Empty";
??? ??????? case DbType.Int16:
??????????????? return "(short)0";
??????????? case DbType.Int32:
??????????????? return "(int)0";
??????????? case DbType.Int64:
??????????????? return "(long)0";
??????????? case DbType.Object:
??????????????? return "new object()";
??????????? case DbType.SByte:
??????????????? return "(sbyte)0";
??????????? case DbType.Single:
??????????????? return "0F";
??????????? case DbType.String:
??????????????? return "String.Empty";
??????????? case DbType.StringFixedLength:
??????????????? return "String.Empty";
??????????? case DbType.Time:
??????????????? return "new DateTime(1900,1,1,0,0,0,0)"; //return "DateTime.MaxValue";
??????????? case DbType.UInt16:
??????????????? return "(ushort)0";
??????????? case DbType.UInt32:
??????????????? return "(uint)0";
??????????? case DbType.UInt64:
??????????????? return "(ulong)0";
??????????? case DbType.VarNumeric:
??????????????? return "(decimal)0";
??????????? case DbType.Xml:
??????????????? return "String.Empty";
??????????? default:
??????????????? return "null";
??????? }
??? }
?
5)??? 文件輸出函數
當然了,做了這么多的工作,最后肯定是希望輸出成文件咯,在前面我們已經說過了,對于輸出的結果是調用Render()方法,那么我們只需要在Render()方法里面輸出文件就可以了。
??? public?override?void Render(TextWriter writer)
??? {
??????? if (!Directory.Exists(OutputDirectory))
??????????? Directory.CreateDirectory(OutputDirectory);
??????? StreamWriter BaseFile = new StreamWriter(OutputFile, false);
??????? base.Render(writer);
??????? BaseFile.Close();
??? }
?
當然了,我們也可以再嵌入的其他模板里面調用這些輸出的方法,從而達到輸出多個文件的目的,這里就不再詳細的寫代碼了。
另附上完整的B的代碼:
<%@?CodeTemplate?ResponseEncoding="UTF-8" TargetLanguage="Text" Src="" Inherits="" Debug="False" CompilerVersion="v3.5" Description="這里是模板說明" %>
<%@ Property Category="Context" Description="這是一個數據表" %>
?
<%@ Assembly %>
<%@ Import Namespace="SchemaExplorer" %>
?
數據表名稱:<%= ThisIsTable.Name %>
?
<% for (int c = 0; c < ThisIsTable.PrimaryKey.MemberColumns.Count; c++) { %>
主鍵<%= c %>:<%= ThisIsTable.PrimaryKey.Name %>
??? <%= ThisIsTable.PrimaryKey.Table.Name %>.<%= ThisIsTable.PrimaryKey.MemberColumns[c].Name %>
<% } %>
?
<% for (int c = 0; c < ThisIsTable.ForeignKeys.Count; c++) { %>
外鍵<%= c %>:<%= ThisIsTable.ForeignKeys[c].Name %>
??? 外鍵<%= c %>對應的列
??? <% for (int i = 0; i < ThisIsTable.ForeignKeys[c].PrimaryKeyMemberColumns.Count; i++) { %>
??????? <%= ThisIsTable.ForeignKeys[c].ForeignKeyTable.Name %>.<%= ThisIsTable.ForeignKeys[c].ForeignKeyMemberColumns[0].Name %> <——來自于 <%= ThisIsTable.ForeignKeys[c].PrimaryKeyTable.Name %>.<%= ThisIsTable.ForeignKeys[c].PrimaryKeyMemberColumns[0].Name %>
??? <% } %>
<% } %>
?
<% for (int c = 0; c < ThisIsTable.PrimaryKeys.Count; c++) { %>
其他表外鍵<%= c %>:<%= ThisIsTable.PrimaryKeys[c].Name %>
??? 其他表外鍵<%= c %>對應的列:
??? <% for (int i = 0; i < ThisIsTable.PrimaryKeys[c].PrimaryKeyMemberColumns.Count; i++) { %>
??????? <%= ThisIsTable.PrimaryKeys[c].PrimaryKeyTable.Name %>.<%= ThisIsTable.PrimaryKeys[c].PrimaryKeyMemberColumns[0].Name %> 作用于——> <%= ThisIsTable.PrimaryKeys[c].ForeignKeyTable.Name %>.<%= ThisIsTable.PrimaryKeys[c].ForeignKeyMemberColumns[0].Name %>
??? <% } %>
<% } %>
?
數據表Select語句:private const String SelectString = @"
??????????? SELECT
??????????????? <% for (int c = 0; c < ThisIsTable.Columns.Count; c++) { %>
??????????????? [<%= ThisIsTable.Columns[c].Name %>]<% if (c < ThisIsTable.Columns.Count - 1) { %>,<% } %>
??????????????? <% } %>
??????????? FROM [<%= ThisIsTable.Name %>] WHERE 1 = 1 ";
???????????
各字段數據類型:
<% for (int c = 0; c < ThisIsTable.Columns.Count; c++) { %>
??? //數據庫類型:DbType.<%= DataType2CSharpType(ThisIsTable.Columns[c].DataType) %>
??? private <%= DataType2CSharpType(ThisIsTable.Columns[c].DataType) %> _<%= ThisIsTable.Columns[c].Name %>;
???
<% } %>
?
<script runat="template">
//將數據庫類型轉化為C#類型
public string DataType2CSharpType(System.Data.DbType dbType)
{
??? switch (dbType)
??? {
??????? case DbType.AnsiString:
??????????? return "string";
??????? case DbType.AnsiStringFixedLength:
??????????? return "string";
??????? case DbType.Binary:
??????????? return "byte[]";
??????? case DbType.Boolean:
??????????? return "bool";
??????? case DbType.Byte:
??????????? return "byte";
??????? case DbType.Currency:
??????????? return "decimal";
??????? case DbType.Date:
??????????? return "DateTime";
??????? case DbType.DateTime:
??????????? return "DateTime";
??????? case DbType.DateTime2:
??????????? return "DateTime";
??????? case DbType.DateTimeOffset:
??????????? return "DateTime";
??????? case DbType.Decimal:
??????????? return "decimal";
??????? case DbType.Double:
??????????? return "double";
??????? case DbType.Guid:
??????????? return "Guid";
??????? case DbType.Int16:
??????????? return "short";
??????? case DbType.Int32:
??????????? return "int";
??????? case DbType.Int64:
??????????? return "long";
??????? case DbType.Object:
??????????? return "object";
??????? case DbType.SByte:
??????????? return "sbyte";
??????? case DbType.Single:
??????????? return "float";
??????? case DbType.String:
??????????? return "string";
??????? case DbType.StringFixedLength:
??????????? return "string";
??????? case DbType.Time:
??????????? return "TimeSpan";
??????? case DbType.UInt16:
??????????? return "ushort";
??????? case DbType.UInt32:
??????????? return "uint";
??????? case DbType.UInt64:
??????????? return "ulong";
??????? case DbType.VarNumeric:
??????????? return "decimal";
??????? case DbType.Xml:
??????????? return "string";
??????? default:
??????????? return "object";
??? }
}
</script>
總結
以上是生活随笔為你收集整理的CodeSmith 基础用法和例子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux命令:MySQL系列之十一--
- 下一篇: hdu 4291 矩阵幂 循环节