NHibernate的子查询多列加盟 [英] Nhibernate subquery with multiple columns join

查看:104
本文介绍了NHibernate的子查询多列加盟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面的关系计划和PlanVersions数据库结构:

  + ------ + +  - ----------- + 
|计划| --------------> | PlanVersion |
+ ------ + 1(1..1)+ ------------- +

PlanVersion是版本表跟踪所有版本的变化,它有 ActiveFromData ActiveToData 列显示了我们,当是这个版本活跃。
计划也可以,可以及时更换子计划让PlanVersion也有 ParrentPlanId 列,告诉我们什么是版本目前的子规划。



我要的是让所有的子计划的所有变化,因为一些时间和具体计划。
这个查询是我想出了:

 定义@Since日期时间; 
组@Since ='2014年8月27日12:00:00.000';

DECLARE @parrentPlan BIGINT;
组@parrentPlan = 1;

选择PV。*
从[DBO]。[PlanVersion] PV
INNER JOIN
/ *查询过的子查询* /

选择PlanId,MAX(ActiveFromDate)AS MaxActiveFromDate
从[DBO]。[PlanVersion] PV
,其中pv.ParentPlanId=@parrentPlan
GROUP BY PlanId
)groupedVersions
在pv.ParentPlanId = groupedVersions.PlanId
和pv.ActiveFromDate = groupedVersions.MaxActiveFromDate
WHERE(pv.ActiveFromDate> = @因为OR pv.ActiveToDate> @Since)

现在我想的是把这一NHibernate的QueryOver:
I有此代码

  VAR子查询= QueryOver.Of< PlanVersion>()
。凡(X => x.ParentPlan.Id == parrentPlanId)
。选择(
Projections.Group< PlanVersion>(E => e.ParrentPlan.Id),
Projections.Max< PlanVersion>(E => e.ActiveFromDate)
);



但我不知道如何写上内两列一起从QueryOver suquery。



注:




  1. 我们在测试中使用NHibernate的3.3与4.0

  2. 此查询将轮询的一部分,所以性能是我


解决方案

我会说,这有解决方案。我们不得不使用更多的复杂的SQL的事实。这种方法我已经深深地了说明:



$ b $查询b

那么,下面就是根据你subqery草案草案。我们正在做的,是建立在事实上是两个子查询(这里检查预期SQL

  PlanVersion planVersion = NULL; 

//最内部的选择
VAR maxSubquery = QueryOver.Of< PlanVersion>()
.SelectList(L =→1
.SelectGroup(项目= > item.ParentPlan.Id)
.SelectMax(项目=> item.ActiveFromDate)

// WHERE子句
。凡(项目=> item.ParentPlan .ID == planVersion.ParentPlan.Id)
// HAVING子句
。凡(Restrictions.EqProperty(
Projections.Max< PlanVersion>(项目=> item.ActiveFromDate),
Projections.Property(()=> planVersion.ActiveFromDate)
));

//中间SELECT
VAR successSubquery = QueryOver.Of< PlanVersion>(()=> planVersion)
//计划ID
。选择( PV => pv.ParentPlan.Id)
.WithSubquery
.WhereExists(maxSubquery)
;



有这个子查询,我们可以要求计划本身:

  //最外层SELECT 
VAR的查询= session.QueryOver<计划和GT;()
.WithSubquery
.WhereProperty(p = > p.Id)
。在(successSubquery)
&的.List LT;计划>();

有可能是一些小的错别字,但草案应该给你明确的答案如何...


I have database structure for Plans and PlanVersions in following relationship:

 +------+                  +-------------+
 | Plan |  --------------> | PlanVersion |
 +------+  1        (1..n) +-------------+

PlanVersion is version table tracking all version changes and it have ActiveFromData and ActiveToData columns show us when was this version active. Plan also can have SubPlans which can change in time so PlanVersion also have ParrentPlanId column which tell us what was current subplan for version.

What i want is to get all changes of all SubPlans since some time and for specific Plan. This query is what i came with:

DECLARE @since datetime;
set @since = '2014-08-27 12:00:00.000';

DECLARE @parrentPlan bigint;
set @parrentPlan = 1;

SELECT pv.* 
FROM [dbo].[PlanVersion] pv
INNER JOIN
    /* Query Over subselect*/
    (
       SELECT PlanId, MAX(ActiveFromDate) AS MaxActiveFromDate
       FROM [dbo].[PlanVersion] pv 
       WHERE pv.ParentPlanId=@parrentPlan
       GROUP BY PlanId
    ) groupedVersions
ON pv.ParentPlanId = groupedVersions.PlanId 
    AND pv.ActiveFromDate = groupedVersions.MaxActiveFromDate
WHERE (pv.ActiveFromDate>=@since OR pv.ActiveToDate>@since) 

Now i want is translate that to Nhibernate QueryOver: i have this code

var subquery = QueryOver.Of<PlanVersion>()
                    .Where(x => x.ParentPlan.Id == parrentPlanId)
                    .Select(
                         Projections.Group<PlanVersion>(e => e.ParrentPlan.Id),
                         Projections.Max<PlanVersion>(e => e.ActiveFromDate)
                    );

But i dont know how to write that inner join on Two columns from suquery in QueryOver.

Notes:

  1. We use Nhibernate 3.3 with 4.0 in testing
  2. This query will be part of polling so performance is really important for me

解决方案

I would say, that this has solution. We have to use a bit more complex SQL in fact. This approach I've already deeply explained here:

So, below is just a draft based on your subqery draft. What we are doing, is creating two subselects in fact (check the intended SQL here)

PlanVersion planVersion = null;

// the most INNER SELECT
var maxSubquery = QueryOver.Of<PlanVersion>()
   .SelectList(l => l
    .SelectGroup(item => item.ParentPlan.Id)
    .SelectMax(item => item.ActiveFromDate)
    )
    // WHERE Clause
   .Where(item => item.ParentPlan.Id == planVersion.ParentPlan.Id)
   // HAVING Clause
   .Where(Restrictions.EqProperty(
      Projections.Max<PlanVersion>(item => item.ActiveFromDate),
      Projections.Property(() => planVersion.ActiveFromDate)
    ));

// the middle SELECT
var successSubquery = QueryOver.Of<PlanVersion>(() => planVersion )
    // the Plan ID
    .Select(pv => pv.ParentPlan.Id)
    .WithSubquery
    .WhereExists(maxSubquery)
    ;

having this subqueries, we can ask for plan itself:

// the most outer SELECT
var query = session.QueryOver<Plan>()
    .WithSubquery
    .WhereProperty(p => p.Id)
    .In(successSubquery)
    .List<Plan>();

There could be some minor typos, but the draft should give you clear answer how to...

这篇关于NHibernate的子查询多列加盟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆