NHibernate - 基于列表属性创建标准

时间:2010-01-20 21:04:58

标签: nhibernate

我有一个名为LoanApplication的类,它有一个名为Workflow的集合属性。在映射文件中,我将工作流记录的检索顺序设置为按日期排序,因此当前工作流始终是列表中的第一项。

现在,我想通过当前工作流程查询,以使用Criteria API获取特定工作流程步骤中的LoanApplications。我真的不确定怎么做。以下是我映射Workflow集合的方法:

<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>

以下是我检索应用程序的方法(这是我需要通过Current Workflow功能添加过滤器的地方):

    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;
    }

感谢您的帮助!

3 个答案:

答案 0 :(得分: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>();

答案 1 :(得分: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?

答案 2 :(得分:-1)

我建议只添加对最后/活动工作流程的引用。标准将更加简单:)

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