我在将T-SQL查询转换为Nhibernate查询时遇到问题 - 或者编写将返回相同结果的查询但是将在NH查询语言中正确编写(HQL,Criteria,QueryOver,LINQ - 我不是真的关心)。
我想从NHibernate执行类似的查询:
SELECT
lic.RegNo,
lic.ReviewStatus
FROM
Licence lic
WHERE
lic.RegNo IN
(
SELECT
grouped.RegNo
FROM
(
SELECT
g.[Type],
g.Number,
MAX(g.Iteration) AS [Iteration],
MAX(g.RegNo) AS [RegNo]
FROM
Licence g
GROUP BY
g.[Type],
g.Number
) as grouped
)
ORDER BY
lic.RegNo desc
如果存在,它会返回最多的许可证并获取其审核状态。 RegNo是从Type,Number和Iteration创建的(模式:{0}{1:0000}-{2:00}
)。每个许可证都可以进行多次迭代,其中一些可以包含ReviewStatus,例如:
W0004-01 NULL
W0001-03 1
P0004-02 3
P0001-02 4
如果迭代部分大于1,则表示存在特定许可的多次迭代(n)。
我已经设法通过两次访问数据库来创建NH查询:
LicenceInfoViewModel c = null;
var grouped = session.QueryOver<Licence>()
.SelectList(l => l
.SelectGroup(x => x.Type)
.SelectGroup(x => x.Number)
.SelectMax(x => x.Iteration)
.SelectMax(x => x.RegNo).WithAlias(() => c.RegNo)
).TransformUsing(Transformers.AliasToBean<LicenceInfoViewModel>())
.Future<LicenceInfoViewModel>();
var proper = session.QueryOver<Licence>()
.Select(x => x.RegNo, x => x.ReviewStatus)
.WhereRestrictionOn(x => x.RegNo)
.IsIn(grouped.Select(x => x.RegNo).ToArray())
.TransformUsing(Transformers.AliasToBean<LicenceInfoViewModel>())
.List<LicenceInfoViewModel>();
// ...
public class LicenceInfoViewModel
{
public string RegNo { get; set; }
public LicReviewStatus? ReviewStatus { get; set; }
}
public enum LicReviewStatus
{
InProgress,
Submitted,
Validated,
RequestForInformation,
DecissionIssued
}
然而,这个解决方案并不好,因为它需要从数据库下载所有分组的许可证,并且可能有数千个。
有没有更好的方法来编写此查询,或者有没有办法将上面提供的T-SQL查询转换为NHibernate?
添加nhibernate和hibernate标签作为IMO如果可以在hibernate中完成它应该很容易翻译成nh
答案 0 :(得分:1)
我不认为SQL会做你认为它做的事情。迭代不用于任何事情。
无论如何,似乎没必要。您可以将WHERE更改为以下内容,并且您将同时拥有有效的SQL和HQL:
lic.RegNo IN
(
SELECT
MAX(g.RegNo)
FROM
Licence g
GROUP BY
g.Type,
g.Number
)