DotNetNuke自定义窗体模块的数据结构(二)


06年底的时候,关于UDT的结构和其他的一些问题,和Sebastian Leupold通过邮件,因为当时费了很大的劲才弄明白数据到底是怎么给弄出来的,DotNetNuke里面像这么难懂的代码还是不太多的,我的建议是把 UDT的数据结构稍微改一下,弄成让大家更舒服一点的,不过估计是大家交流上还是有点障碍,毕竟E文都不是母语(SL是德国佬);后来想:算了,还是自己弄吧,于是从这个数据结构出发,把它给优化了一下,成了我的数据结构,希望不会让大家觉得太烂。

  首先再贴一张图,分析一下UserDefinedTable的情况

  (原来的数据结构存储)

  我把三张表的数据弄到一块了,这样大家可以看得更清楚一点。上图中可以看到,UserDefinedFields是一个字段定义器存放的数据,比如我们的字段名称、初始值、顺序等,这个表可以理解为一个“结构表”;而下面的UserDefinedRows是“主记录表 ”,UserDefinedData是“从记录表”。我们的表格结构是存放在Fields表里面的,而所有的表格内容,都是存放在Rows和Data这两张表中的。

  大家可以看到,UserDefinedRows这张表只有两个字段,其实,除了几乎每个用户开发模块都有的ModuleId(是为了在不同的模块中显示不同的数据),那么,就只有一个字段,也就是UserDefinedRowID,这张表太浪费了!

  而我们再回头想一下我们通常使用的列表/窗体,其实,对于“列表/窗体”这种模式来说,显示在列表上的必然只是有限的几个字段而已,而大量的字段,是不需要显示在列表上的,所以,我们的改造就是,把需要在列表上显示的,尽量的放在UserDefinedRows这张表中,那么,其实,我们读取数据的时候,就不需要弄那么复杂的LEFT JOIN,也不需要在内存中动态生成DataTable了,这种方式,当然是可以大大提高执行效率的。改进后的数据结构,可能是如下图所示的:

  OK,其实看过这张图大家应该知道我的想法了,就是把数据分成两部分,一部分是需要(或者是可能需要)在列表上进行展示的(还有,比如要在查询条件中出现的、要参与系统查询接口的等等),我们尽量将之放在UserDefinedRows这张表中;另外一部分是只是在打开表格中才会用到或者读取的,我们将之放在UserDefinedData这张表中。这个时候,如果我们再要读取数据的话,那就非常简单的,可能的SQL语句就是如下这种样式的:

   SELECTUserDefinedID,Field1AS姓名,Field2AS性别,Field3AS年龄FROMUserDefinedRows

  只是在编辑或者查看详细的内容的时候,我们才需要去读取UserDefinedData这张表,所以,效率上肯定不会有问题。既然我们对这个数据结构作了修改,那么,字段定义表UserDefinedFields这张表的结构当然也需要修改一下,至少要标明哪些字段是“基本字段”(也就是在 UserDefinedRows中出现的字段),哪些是扩展字段(也就是在UserDefinedData中出现的字段),其他的,根据我们的业务需要去进行扩展就可以了。

  在让用户进行表单定义的时候,可以告诉用户,如果需要在列表上显示和查询的,就尽量使用基本字段;其他的,则任意定义。

  通过这种方式,我们把UserDefinedTable这个模块往前提升了一步,仍然支持无限的字段定义,但是,在缺省的Control(也就是View界面)上读取数据的时候,我们尽量抛弃UDT原来的非常让人头疼的方式。

  为了让数据更加规范,我们在增加UserDefinedRows表的字段的时候,做严格的数据类型限制(而不需要像 UDTData表那样统一的采用ntext类型,或者是varchar类型),这样的好处就是存储的数据是绝对严格的,程序出错的几率更小。如果大家用 varchar字段存储过日期格式、数值格式,而又碰到过需要对这些字段进行拼凑SQL语句查询的话,大家就明白我在说什么了,那种出错的痛苦(数据格式不规范,如本来应该是日期型,结果实际存储的不是,于是,日期转换函数报错),简直就是让人欲哭无泪。

  所以……,是的,在大家崩溃之前,我要告诉大家,我已经把UserDefinedRows的两个字段扩展到几十个字段了,就是上图这个庞然的数据结构,看到其中的ParentID了?是的,我让这个玩意儿也支持树形结构了!如果大家有足够的耐心给我足够的时间的话,应该可以看到我的解释。(还有FormID、KeyID等,也需要解释)

  反倒是UserDefinedData这张表,和原来没什么太大的不同,这里我们就不贴图了。

  好了!为了遍历和查询的快捷性以及准确性,我们把UserDefinedRows这张表给扩展了,增加了数据结构,并且要求严格限制数据类型;而为了支持动态窗体的无限字段支持,我们仍然保留了UserDefinedData这张表。不要LEFT JOIN,不要在内存里面动态生成DataTable,那都是太浪费效率的方式。

  弄完数据结构之后,马上我们就面临一个问题了,那就是用存储过程是不太好更新我们的数据结构的,所以,下面我们要做的事情,就是把DotNetNuke传统的使用存储过程保存数据的方式也改掉(当然,仍然没有动及DotNetNuke的开发结构,这个是我们不能动的)。我们下一部分来谈这个问题,我们将会使用哈希表的结构,来动态的更新这张表


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3