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

时间:2013-04-30 19:00:23

标签: nhibernate

我在MS SQL中定义了一个DB密集型函数,它计算LastCompletedDate对象的只读属性(Inspection)。我通常不需要这些信息,所以我没有将其映射到Inspection.hbm.xml

当我确实需要这些信息时,我想获取一个IEnumerable的Inspections集合,查询数据库以找到他们的LastCompletedDate,然后为每个人填写。{1}}。理想情况下,不为每个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 个答案:

答案 0 :(得分:1)

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

  1. 将该属性标记为延迟加载

    <property name="LastCompletedDate" 
              lazy="true" 
              formula="dbo.fn_GetLastCompletedDate(InspectionId)"/>
    

    执行查询以获取所有检查对象时,不会加载此属性。

    CurrentSession.CreateQuery("from Inspection")
                  .List<Inspection>();
    

    但是当包含提示时,此属性将与所有其他属性一起加载。

    CurrentSession.CreateQuery("from Inspection fetch all properties")
                  .List<Inspection>();
    

    这种方法的缺点是this hint is only available when using 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一起使用。所以我给出的查询示例是错误的,因此组件方法的优点也是如此。