我在MS SQL中定义了一个数据库密集型函数,用于计算Inspection
对象的只读属性(LastCompletedDate
)。我通常不需要这些信息,所以我没有在Inspection.hbm.xml
中映射它。
当我需要的信息,我想采取Inspections
的IEnumerable集合,查询数据库找到他们的LastCompletedDate
,并填写每个。理想情况下,不需要为每个Inspection
单独访问数据库。我在NHibernate中找不到这样做的方法(我是NHibernate的相对新手)。我在想这样写:
CurrentSession.CreateQuery(
"select InspectionId, dbo.fn_GetLastCompletedDate(InspectionId)
from Inspection where InspectionId in :idList")
.SetParameter("idList", from InspectionList select InspectionId)
.List();
后面是一个循环,以取出日期并将它们添加到Inspection对象中。
有更好的方法吗?我需要什么语法?
我能想到两种可能的选择。
-
将属性标记为惰性加载
<property name="LastCompletedDate" lazy="true" formula="dbo.fn_GetLastCompletedDate(InspectionId)"/>
当执行查询以获取所有Inspection对象时,此属性将不会被加载。
CurrentSession.CreateQuery("from Inspection") .List<Inspection>();
但是当包含提示时,此属性将与所有其他属性一起加载。
CurrentSession.CreateQuery("from Inspection fetch all properties") .List<Inspection>();
这种方法的缺点是该提示仅在使用HQL时可用。详情请点击此处
http://ayende.com/blog/4377/nhibernate-new-feature-lazy-properties -
第二个选项是使用一个启用了延迟加载的组件。
<component name="lazy_load_items" lazy="true"> <property name="LastCompletedDate" formula="dbo.fn_GetLastCompletedDate(InspectionId)"/> </component>
再次,这是延迟加载的,因此对Inspection实体的正常查询不会导致对每行调用函数
CurrentSession.QueryOver<Inspection>.List();
但是它可以通过任何查询api来加载
session.QueryOver<Inspection>() .Fetch(i => i.lazy_load_items).Eager .List();
这种方法的缺点是需要创建一个额外的类来包含您的单个属性。
更新在进一步的测试中,看起来组件的即时加载只适用于使用
fetch all properties
提示的HQL。所以我给出的查询示例是错误的,因此组件方法的优点也是错误的。