DbEntry MVC 开发小记
花了一周左右的时间,使用 DbEntry.Net 的 MVC 把 我的网站 重新设计了一下,同时也可以算是对 DbEntry.Net MVC 的一次实用性测试及升级。在这里记录一些感想。
DbEntry.Net MVC 更像 Ruby onRails,使用的脚手架方式也类似,以前我就觉得,脚手架是挺重要的,在这次开发中,也实际的感觉到脚手架的好处。事实上,直到现在网站已经上线运行,还有一些管理员功能是直接使用脚手架的。在敏捷开发中,数据Model可能随着开发进度的发展而发生变化,特别在开发初期,很多不确定因素会导致Model的变化,所以一个好的脚手架模块,应该是能尽量延迟其被实体化的时间,一旦其被实体化,数据Model的变化,就很可能导致这些代码的变化。所以,我觉得脚手架就不能是代码生成器,即使代码生成器可以作为“编译前事件”而做到每次Model的变化都得到表现,却很难判断是否用户修改过被生成的代码,用户修改过的代码被覆盖,会是一件很让人丧气的事。一般来说,Controller的脚手架代码不太需要修改,主要需要修改的是View,为了尽量增加脚手架View的生命周期,我为脚手架View增加了对于MasterPage的支持,虽然即使这样,脚手架的View看起来还是有些简陋,不过,至少是和整体网站的风格统一了,用户也可以看到和使用MasterPage里的链接,可以尽量等到Model之类的变量比较确定的时候,再加入定制的View。
以前在 javaeye 的一个帖子 ruby on rails为什么暂时无法成为企业应用开发的主流?里讨论说 RoR 似乎鼓励所有的代码都写到一个 controller 里,比如 javaeye 的 blog 就只有一个controller,我曾回贴说可能 XP 开发的话,是否只有一个 controller 也无所谓,当然,我现在也还是认为 XP开发的话,确实可以在很大程度上改善这种情况,不过,在这次开发中,我却觉得,是否所有功能都写在一个 controller里,更多的是一个设计问题。在开始的一两天里,我确实也把很多功能都放在了 ArticleController 里,article/rss,article/category 等也看起来挺顺的,但是,它把 rss, category 的代码混入了 article,而只要改变为rss/article 和 category/show,它的代码就被放在了另外一个 controller 里,而且,职责也更清晰,对RssController 来说,支持 rss/comment 也更理所当然了。
在这次网站的设计中,我第一次大量使用了 Static Page 方式。这是以前我为 DbEntry设计的一个用于分页的算法,其源于使用搜索引擎的郁闷。很多时候,我们搜索一个东西,搜索引擎显示其链接,等我们点击进去后,却发现我们所在分页根本就没有我们要查的信息。原因在于,只要有新的文章不断加入,常用的分页算法对于特定文章的 PageIndex将会发生变化,比如最早的文章,将会随着新文章的加入,而逐渐变为第二页、第五页、第二十八页……。而解决这个问题的方法,就是类似动态页面静态化的想法,最早的文章不应该是80页、90页,而总应该是第1页,最新的文章才应该是80页、90页。静态分页有一个问题,就是包含最新记录的页面可能不到PageSize 那么大,如果显示在首页的位置,有时候会显得比较单薄,所以,在这次开发中,我增加了 Hybird方式,首页使用传统分页,之后使用静态分页。
说是网站重新设计,在于以前的数据库结构完全放弃了,在这次开发中 Model完全由构想的使用方式决定,而跟老的数据库结构关系不大,比如,老的数据库结构是固定两层 Category,有 topic,有keyword,而在新的数据库结构中,只有一层 Category,而把以前的第二层 Category 和 topic、keyword 都作为Tag 处理。这当然导致数据库迁移显得比较麻烦,使用 DbEntry 的 BulkCopy,在一定程度上缓解了这个矛盾,对于 BulkCopy来说,需要编写的是针对源数据库的 SQL 语句,目标数据库的 SQL 语句是由 BulkCopy自动根据目标数据库类型生成的,所以我仍然可以使用一份代码,从源数据库生成 sqlite 数据库用于开发,生成 Firebird数据库用于部署。不过,因为 Firebird 使用的是序列方式产生主键,而 BulkCopy 不涉及ORM,所以它不会去操作序列,虽然不需要像 Sql Server 插入主键那样调用 SET IDENTITY_INSERTON,但是却需要在导入数据后,重新设置序列,以便其能正确的产生主键,我使用的方法可能笨一点儿,就是用 max(id) 取得最大 id值,再多次调用 select 去取相关序列,反正速度挺快的,应该也不需要多聪明的方法吧。不过也发现在 Firebird 上用ExecuteNonQuery 调用 select 取序列的话,根本不会执行......
网站的 footer 上,写上 Powered By DbEntry.Net,感觉挺爽的,考虑稍微修改一下许可协议,如果有项目要使用 DbEntry.Net 的话,也要在经常能见到的地方写上 Powered By DbEntry.Net :)