如何为列表中的每个成员运行NHibernate的DB函数



我在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对象中。

有更好的方法吗?我需要什么语法?

我能想到两种可能的选择。

  1. 将属性标记为惰性加载

    <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

  2. 第二个选项是使用一个启用了延迟加载的组件。

    <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。所以我给出的查询示例是错误的,因此组件方法的优点也是错误的。

相关内容

最新更新