具有多列联接的Nhibernate子查询
本文关键字:Nhibernate 查询 | 更新日期: 2023-09-27 18:19:40
我有计划和计划版本的数据库结构,关系如下:
+------+ +-------------+
| Plan | --------------> | PlanVersion |
+------+ 1 (1..n) +-------------+
PlanVersion是跟踪所有版本更改的版本表,它有ActiveFromData和ActiveToDataarrentPlanId列,告诉我们版本的当前子计划是什么。
我想要的是得到一段时间以来所有子计划和特定计划的所有更改。这个查询就是我附带的:
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)
现在我想把它翻译成Nhibernate QueryOver:我有这个代码
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)
);
但我不知道如何在QueryOver中编写suquery的Two列的内部联接。
注:
- 我们在测试中使用了Nhibernate 3.3和4.0
- 这个查询将是轮询的一部分,所以性能对我来说非常重要
我想说,这是有解决方案的。事实上,我们必须使用稍微复杂一点的SQL。我已经在这里深入解释了这种方法:
- HasMany参考文献查询
所以,下面只是基于您的子查询草稿的草稿。事实上,我们正在做的是创建两个子选择(请在此处查看预期的SQL)
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)
;
有了这些子查询,我们可以要求计划本身:
// the most outer SELECT
var query = session.QueryOver<Plan>()
.WithSubquery
.WhereProperty(p => p.Id)
.In(successSubquery)
.List<Plan>();
可能有一些小的打字错误,但草案应该给你明确的答案如何…