在上篇随笔《代码生成工具之界面快速生成》中介绍过了代码生成工具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的基本语法,结合代码工具提供的数据库元数据信息,我们可以做的更多,做的更好。希望这个工具对你的开发有帮助。