<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    〇、            前言


    最近兩天自己寫了個簡單的ORM框架,非常的Easy,但是沒有相應的代碼生成工具,于是就很杯具了!


    于是乎,花費了一天的時間學習并寫了一個CodeSmith可以使用的模板。在此記錄下CodeSmith的學習筆記。


    所用工具: CodeSmith Professional v5.1.3.8510,代碼示例全部是以C#為例。


    一、            工具設置


    CodeSmith默認是不支持中文的,那么我們必須要先設置使其支持中文顯示,保存。并且要能夠在生成文件中支持中文。



    1. [Tools->Options...->Studio->Editor->Enable
      unicode]將這個選項勾上,那么CodeSmith就可以顯示和保存中文了。
    2. 在你的模板的最前面的一句話,C#為例:

    <%@ CodeTemplate
    TargetLanguage="Text" Src="" Inherits="" Debug="False" CompilerVersion="v3.5"
    Description="Template description here." %>


    中加入ResponseEncoding="UTF-8" 的標簽。將會使得生成的文件也支持中文。



    1. [Tools->Options...->Studio->Editor->Convert tab
      to]去掉這個的勾選,就是不使用空格來替換Tab。

     


    二、            模板區域說明


    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>

    http://www.cnblogs.com/sorex/archive/2009/12/24/1631533.html
    posted on 2013-06-15 15:31 sanmao 閱讀(1059) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    常用鏈接

    留言簿(5)

    隨筆分類

    隨筆檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲无码在线播放| 又爽又高潮的BB视频免费看| 亚洲精品无码av人在线观看 | 国产亚洲精品资源在线26u| 免费的黄色的网站| 亚洲国产成人久久综合区| yellow免费网站| 亚洲视频在线一区二区| 国产成人无码免费网站| 久久被窝电影亚洲爽爽爽| 亚洲a一级免费视频| 亚洲精品亚洲人成在线麻豆| 99久久免费观看| 在线亚洲午夜片AV大片| 暖暖日本免费在线视频 | 亚洲一区二区久久| 好吊妞视频免费视频| 国产亚洲人成在线影院| 中文字幕在线亚洲精品| 91av免费观看| 久久久久亚洲国产AV麻豆| 亚洲精品黄色视频在线观看免费资源| 2022免费国产精品福利在线| 久久亚洲伊人中字综合精品| 日韩视频在线精品视频免费观看 | 国产精品亚洲а∨无码播放| 99久久人妻精品免费二区| 亚洲天堂2016| 亚洲国产精品13p| 97青青草原国产免费观看| 亚洲欧美日韩一区二区三区在线| 亚洲国产电影av在线网址| 国产99视频精品免费专区| 国产午夜亚洲精品| 国产亚洲精品资在线| 日韩欧毛片免费视频| 免费无码一区二区| 亚洲va乱码一区二区三区| 亚洲AⅤ视频一区二区三区| 在线日本高清免费不卡| 免费在线人人电影网|