2010-01-20 53 views
1

我有一個名爲LoanApplication的類,它有一個名爲Workflow的集合屬性設置。在映射文件中,我將工作流記錄的檢索順序設置爲按日期排序,因此當前工作流始終是列表中的第一項。NHibernate - 基於屬性列表創建標準

現在我想通過當前工作流查詢,以使用Criteria API獲取特定工作流步驟中的LoanApplication。我不確定如何做到這一點。這裏是我正在繪製工作流程集合:

<bag name="ApplicationWorkflow" table="PreApplication.ApplicationWorkflow" generic="true" inverse="true" order-by="StartDate DESC" 
    cascade="all" lazy="true"> 
    <key column="ApplicationID" /> 
    <one-to-many class="ApplicationWorkflow" /> 
</bag> 

這裏是我正在檢索應用程序(這是我需要通過當前工作流功能來添加過濾器):

public IList<Model.PreApplication.Application> GetCompletedApplications() 
    { 
     IList<Model.PreApplication.Application> result = null; 

     using (ITransaction transaction = this.Session.BeginTransaction()) 
     { 
      result = this.Session.CreateCriteria<Model.PreApplication.Application>() 
       .AddOrder(new Order("EnteredDate", false)) 
       .List<Model.PreApplication.Application>(); 

      transaction.Commit(); 
     } 

     return result; 
    } 

感謝您的任何幫幫我!

回答

2

因此,您需要列出當前工作流程在特定步驟的應用程序?您可以使用子查詢僅加入當前工作流程,然後限制爲特定步驟。

所需的SQL ...

select 
    ... 
from 
    Application app 
    inner join ApplicationWorkFlow currWorkFlow on app.id = currWorkFlow.application_id 
where 
    currWorkFlow.id = (
     select top 1 topFlow.id 
     from ApplicationWorkFlow topFlow 
     where topFlow.application_id = app.id 
     order by topFlow.StartedDate desc 
    ) 
    and currWorkFlow.step = @step 

條件來讓你有...

session.CreateCriteria<Application>("app") 
    .CreateAlias("ApplicationWorkFlow", "currWorkFlow", NHibernate.SqlCommand.JoinType.InnerJoin) 
    .Add(Subqueries.PropertyEq("currWorkFlow.id", 
     DetachedCriteria.For<ApplicationWorkFlow>("topFlow") 
      .SetMaxResults(1) 
      .SetProjection(Projections.Property("topFlow.id")) 
      .AddOrder(Order.Desc("topFlow.StartDate")) 
      .Add(Restrictions.EqProperty("app.id", "topFlow.Application.id")))) 
    .Add(Restrictions.Eq("currWorkFlow.step", step)) 
    .List<Application>(); 
+0

希望我能給你10個upvotes。謝謝! –

0

我建議只添加最後/活動工作流的參考。標準將更簡單:)

public void AddLatestWorkflow(Workflow wf) 
{ 
    this.Workflows.Add(wf); 
    this.LatestWorkflow = wf; 
} 
+0

我不確定你在說什麼。除了保留所有工作流程的列表之外,添加另一個屬於最新工作流程的屬性?如果這就是你所說的,你能告訴我如何獲得屬於最新工作流的財產嗎? –

+0

我添加代碼示例。 – dariol

1

這個怎麼樣的SQL查詢?

SELECT * FROM Application app 
JOIN 
    (SELECT * FROM ApplicationWorkFlow aflo WHERE aflo.step = @step) AS aflo 
WHERE aflo.application_id = app.id 

使用簡化的查詢條件

var applications = 
    Session.CreateCriteria<Application>() 
      .CreateAlias("ApplicationWorkFlow", "appflo", JoinType.LeftOuterJoin) 
      .Add(Restrictions.Eq("appflo.Step", step)) 
      .List<Application>(); 

使用分離標準

var detached = DetachedCriteria.For<ApplicationWorkFlow>() 
           .SetProjection(Projections.Id()) 
           .Add(Restrictions.Eq("Step", step)); 

var applications = 
     Session.CreateCriteria<Application>() 
       .CreateAlias("ApplicationWorkFlow", "appflo", JoinType.LeftOuterJoin) 
       .Add(Subqueries.PropertyIn("appflo.Id", detachedCriteria)) 
       .List<Application>(); 

通訊條件查詢可能有人請告訴我,如果上述兩個查詢是一樣的嗎?他們正在生成相同的SQL在我的情況。如果它們相同,爲什麼要使用DetachedCriteria?

+0

謝謝!你是第一個簡化的查詢要簡單得多,並幫助我得到我所需要的。 +1 – tofortier