庆祝NHibernate 3.0 GA 正式发布。内牛满面...
同时,基于现有的一些需求,思考两个问题;思考而已,还没有时间测试:
问题1:
背景:某系统,所有的数据采用软删除,即,实体中都有一个属性,如RecordStatus = 0时,代表数据为正常状态;等于1时代表数据为已删除。于是在实体的hbm文件中添加where="RecordStatus = 0 OR RecordStatus IS NULL"。
问题场景:在某些特定场合,需要加载RecordStatus <> 0 的数据。
可能解决方案:最直接的设想,当然是在需要加载RecordStatus <> 0的数据的场景下动态地Disable配置中的where condition. 但经过研究,发现这个方法不可行,因为当SessionFactory创建完毕后,配置中的内容不可更改(尚待更进一步的测试)。替代方案是在有这个需要的场景之下,重新创建SessionFactory,并且采用不包含where condition的配置文件。然后再用这个SessionFactory来创建Session。在3.0中,可以这么做:
http://www.primordialcode.com/blog/post/modify-nhibernate-mappings-runtime
2.x可以这么做:
http://stackoverflow.com/questions/702195/adding-an-nhibernate-mapping-at-run-time
(顺便记下,读取配置信息:http://stackoverflow.com/questions/281095/nhibernate-accessing-configuration-properties-sql-dialect-at-runtime)
当然这种解决方案是以性能为代价的,因为创建SessionFactory是个重体力活,据说耗时约1秒。
另一个可能可行的方案,有待测试:
用Interceptor。监听PreLoad事件,在此事件中做特殊处理。
当然,最肯定能解决问题的方案就是不要加这个where condition,然后在所有的使用到的场景中动态地添加适当的过滤条件。
还有一个办法,就是需要加载的时候,添加OR RecordStatus =1 的条件,这样既可绕开。有待测试.
2010-12-12 最终结论:无法绕开。但是这样的场景可以把where用filter替代。
问题2: Lazy load property.
例如,某表某列数据庞大,我们希望在默认情况下都不加载此列。在3.0下,这个可以做到了:
http://ayende.com/Blog/archive/2010/01/27/nhibernate-new-feature-lazy-properties.aspx
当然,这里的问题是文章里提到了怎样用Query来明确获取所有的Lazy Properties,但也说明了无法精确控制特定Property,也无法通过Criteria来获取Lazy Properties。当然这是2010/01/27的文章,当前正式版本的真实情况如何,有待研究。
另外,此文章的回复中,提到了用ExludeProperty方法来做类似的事情。诚然,这个方法需要每次动态地去指定,而非“默认”不加载的概念。
http://efreedom.com/Question/1-3669164/NHibernate-ExcludeProperty-IncludeProperty
上面说了一个挺有意思的IncludeProperty的实现,记下,可参考。
而这个的回复提到的东西有空试试: