在上篇隨筆《代碼生成工具之界面快速生成》中介紹過了代碼生成工具Database2Sharp是如何快速生成所需的Web界面以及各種Winform界面,其中包括生成即可運行的Web界面效果,Winform布局信息的生成。這些看似很簡單的界面元素生成,其實是需要豐富的數據庫元數據信息作為基礎的,而且對不同的數據庫處理要有所不同。本文介紹不同數據庫之間元數據的處理差別,以及如何代碼生成工具Database2Sharp如何兼容處理這些問題的。
1、常規的數據庫表、字段名稱的轉義
例如,我們需要獲取表的別名,對於SqlServer一般設計的時候是采用Pascal命名方式,所以表名稱不需要轉義,但對於Oracle表名稱,基本上都是以大寫來命名,而且表名稱不是采用Pascal方式,而是兩個詞之間采用下划線“_"來分隔的,如DEPT_NAME這樣的名稱。
一般來說,我們為每種的數據庫定義一套轉義規則,來為表、字段名稱增加一個別名字段,如Oracle的DEPT_NAME我們設法讓它別名顯示為DeptName就可以了,SQLServer的由於一般名稱都是Pascal的,我們可以不用轉義,數據庫表、字段名稱為DeptName,我們就保留它作為別名DeptName即可。
我的代碼生成工具的元數據屬性就是這樣的模式,有一個NameElement對象,就包含Name和Alias兩個屬性,如下所示。
2、特別情況下的表、字段名稱轉義
但我們有時候反向工程的時候,可能數據庫是從Oracle到SQLServer的,或者有時候考慮多數據庫兼容的情況,那么可能SQLServer的表及字段的名稱還是Oracle的命名規則的,如下SQLServer例子所示。
對於以上的數據庫信息,如果沒有轉義數據庫名稱,那么就給生成代碼造成很大的困擾,因為實體類屬性名稱,類名稱都可能是Oracle風格的大寫的標志,非常不利於閱讀。
但代碼生成工具已經增加了智能識別字段名稱的邏輯,對於這種從Oracle過來的數據庫命名規則,我們也能合理生成對應的代碼,如上圖的右邊,它已經判斷使用了Oracle的命名規則來處理別名了。
這樣我們生成的代碼,就是很友好的命名風格了。
3、自定義表、字段名稱的別名
有時候,統一規則生成的別名不一定是我們所需要的,那么請使用代碼生成工具的別名設置操作即可把某個表名、字段名設置為你想要的名稱,如下操作所示。
1)表別名修改
2)字段別名修改
4、在代碼工具的自定義模板中使用字段轉義信息
代碼生成工具Database2Sharp提供了很好的自定義模板操作交互功能,我們只需要在模板文件中書寫NVelocity的模板代碼就可以輸出各種豐富多彩的代碼的,如下面圖就是自定義模板列表界面,其中左邊列出一些基礎的例子模板代碼,大家可以參考學習,在樹形目錄中建立自己的模板文件和模板代碼。
使用自定義模板代碼的目的,就是要利用數據庫的元數據信息來生成復雜而有規律的代碼片段或者文件的。
我們注意到模板代碼,其中利用到的數據庫信息及遍歷操作等。
/// <summary> /// 初始化 /// </summary> /// <param name="info">實體類信息</param> private void InitData(${ClassName}Info info) { #foreach($ColumnInfo in ${TableInfo.ColumnList.Values}) #if(${ColumnInfo.AutoIncrement} == false) #if(${ColumnInfo.NetType} == "System.String" ) this.txt${ColumnInfo.Name.Alias.ToCapit()}.Text = info.${ColumnInfo.Name.Alias.ToCapit()}; #elseif(${ColumnInfo.NetType} == "System.DateTime") this.txt${ColumnInfo.Name.Alias.ToCapit()}.Text = info.${ColumnInfo.Name.Alias.ToCapit()}.ToShortDateString(); #else this.txt${ColumnInfo.Name.Alias.ToCapit()}.Text = info.${ColumnInfo.Name.Alias.ToCapit()}.ToString(); #end #end ##endif #end } /// <summary> /// 獲取數據 /// </summary> private ${ClassName}Info GetData() { ${ClassName}Info info = new ${ClassName}Info(); #foreach($ColumnInfo in ${TableInfo.ColumnList.Values}) #if(${ColumnInfo.AutoIncrement} == false) #if(${ColumnInfo.NetType} == "System.Decimal" ) info.${ColumnInfo.Name.Alias.ToCapit()} = Helper.SafeConvertDecimal(this.txt${ColumnInfo.Name.Alias.ToCapit()}.Text); #elseif(${ColumnInfo.NetType} == "System.DateTime") info.${ColumnInfo.Name.Alias.ToCapit()} = Helper.SafeConvertDate(this.txt${ColumnInfo.Name.Alias.ToCapit()}.Text); #else info.${ColumnInfo.Name.Alias.ToCapit()} = this.txt${ColumnInfo.Name.Alias.ToCapit()}.Text; #end #end ##endif #end }
其中的${ColumnInfo.Name.Alias.ToCapit()}為別名,而${ColumnInfo.Name.Name.ToCapit()}為數據庫表字段真實名稱。
以上模板,我們選擇數據庫表生成代碼,就可以得到下面的標准賦值及獲取內容的代碼了。
/// <summary> /// 初始化 /// </summary> /// <param name="info">實體類信息</param> private void InitData(GroupInfo info) { this.txtEditor.Text = info.Editor.ToString(); this.txtEdittime.Text = info.Edittime; this.txtName.Text = info.Name; this.txtOutGroup.Text = info.OutGroup; this.txtGroupOrder.Text = info.GroupOrder; this.txtDeptName.Text = info.DeptName; this.txtUpperDept.Text = info.UpperDept.ToString(); this.txtGrade.Text = info.Grade.ToString(); this.txtRemark.Text = info.Remark; } /// <summary> /// 獲取數據 /// </summary> private GroupInfo GetData() { GroupInfo info = new GroupInfo(); info.Editor = this.txtEditor.Text; info.Edittime = this.txtEdittime.Text; info.Name = this.txtName.Text; info.OutGroup = this.txtOutGroup.Text; info.GroupOrder = this.txtGroupOrder.Text; info.DeptName = this.txtDeptName.Text; info.UpperDept = this.txtUpperDept.Text; info.Grade = this.txtGrade.Text; info.Remark = this.txtRemark.Text; }
以上就是代碼生成工具Database2Sharp的數據庫表及字段名稱轉義的智能處理以及應用,如果熟練使用NVelocity的基本語法,結合代碼工具提供的數據庫元數據信息,我們可以做的更多,做的更好。希望這個工具對你的開發有幫助。