NHibernate映射多对一fetch =“join”公式

时间:2012-08-27 14:17:40

标签: nhibernate-mapping

我得到了表格:

PROCESSES  STEP_STATUSES  STEPS
---------  -------------  -----------
PROC_ID    STAT_ID        STEP_ID
PROC_NAME  NAME           STEP_NUMBER
...                       STEP_NAME
                          ...
                          STAT_ID
                          PROC_ID

有没有办法可以使用属性CurrentStep(这是一个映射的STEPS表行)将Processes表映射到NHibernate?

我几乎可以通过映射做到我需要的东西:

<many-to-one name="CurrentStep" formula="(
  select t.step_id
  from STEPS t
  where PROC_ID = t.PROC_ID 
    and STEP_NUMBER = nvl((select max(STEP_NUMBER), PROC_ID from STEPS where STAT_ID > 0 and PROC_ID = t.PROC_ID),
                                (select min(STEP_NUMBER), PROC_ID from STEPS where STAT_ID = 0 and PROC_ID = t.PROC_ID))
)"/>

但我无法设置fetch =&#34;加入&#34;对于这个字段,我想用一个查询获取所有数据,与CurrentStep属性值一起获取 - 就像这样:

select t.*, st.*
from PROCESSES t
left outer join (
    select STEP_ID, PROC_ID 
    from STEPS s1
    where STEP_NUMBER = nvl((select max(STEP_NUMBER) from STEPS where STAT_ID > 0 and PROC_ID = s1.PROC_ID),
                            (select min(STEP_NUMBER) from STEPS where STAT_ID = 0 and PROC_ID = s1.PROC_ID))
          ) s on s.PROC_ID = t.PROC_ID
left outer join STEPS st on st.PROC_ID = s.PROC_ID and st.STEP_ID = s.STEP_ID

由于表现,这是必要的。

所以,问题是:

  1. 有没有办法设置fetch =&#34; join&#34;对于这样一个复杂的公式领域?
  2. 有没有办法加入这样一个复杂的子查询?
  3. 如果无法设置映射,有没有办法创建ICriteria来获取此类查询结果?
  4. 对不起,如果问题不明确,如果出现任何问题,我会尝试澄清/

1 个答案:

答案 0 :(得分:1)

使用批量读取查询所需内容的想法

var lastStepWithStatus = session.CreateCriteria<Step>()
    .Add(Restriction.Eq("Process.Id", processId))
    .Add(Restriction.NotNull("Status"))
    .AddOrder(Order.Desc("Number"))
    .SetMaxResults(1)
    .Future<Step>();

var firstStepWithoutStatus = session.CreateCriteria<Step>()
    .Add(Restriction.Eq("Process.Id", processId))
    .Add(Restriction.IsNull("Status"))
    .AddOrder(Order.Asc("Number"))
    .SetMaxResults(1)
    .Future<Step>();

return lastStepWithStatus.Concat(firstStepWithoutStatus).Select(step => new { Process = Step.Process, CurrentStep = step }).FirstOrDefault();

另一种选择是在Steps集合上使用LINQ来获取当前步骤,这意味着首先加载所有步骤。