0

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

当我确实需要信息时,我想获取一个 IEnumerable 集合Inspections,查询数据库以找到它们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();

然后是一个循环来提取日期并将它们添加到检查对象中。

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

4

1 回答 1

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>();
    

    这种方法的缺点是该提示仅在使用 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>
    

    同样,这是延迟加载的,因此针对检查实体的正常查询不会导致为每一行调用函数

    CurrentSession.QueryOver<Inspection>.List();
    

    但它可以通过任何查询 API 预先加载

    session.QueryOver<Inspection>()
           .Fetch(i => i.lazy_load_items).Eager
           .List();
    

    这种方法的缺点是需要创建一个额外的类来包含您的单个属性。

    更新

    在进一步的测试中,似乎急切加载组件仅适用于使用fetch all properties提示的 HQL。所以我给出的查询示例是错误的,因此组件方法的优势也是如此。

于 2013-04-30T20:33:55.943 回答