0

我正在使用 nHibernate 3.3。我想像这样执行 SQL:

select COUNT(*) from (
SELECT YEAR(MeasureDateLocal) As [Year], MONTH(MeasureDateLocal) As [MONTH], DAY(MeasureDateLocal) As [DAY], sum(this_.RainCounterValue) as y3_
FROM DriverPeriphMeasure this_
WHERE this_.IdDriver = @p1
GROUP BY YEAR(MeasureDateLocal), MONTH(MeasureDateLocal), DAY(MeasureDateLocal) ) s 

但使用 QueryOver 或 LINQ。目前我有这个丑陋的代码:

var countQuery = Context.Session.CreateSQLQuery(
    @"select COUNT(*) from 
    (SELECT YEAR(MeasureDateLocal) As [Year], MONTH(MeasureDateLocal) As [MONTH], DAY(MeasureDateLocal) As [DAY], sum(this_.RainCounterValue) as y3_ 
    FROM DriverPeriphMeasure this_ 
    WHERE this_.IdDriver = :driverID
    GROUP BY YEAR(MeasureDateLocal), MONTH(MeasureDateLocal), DAY(MeasureDateLocal) ) s" )
.SetParameter<Guid>( "driverID", driver );
int total = countQuery.UniqueResult<int>();

但我很想看看如何使用 QueryOver 来做到这一点。我设法编写了以下 QueryOver:

var q3 = Context.Session.QueryOver<DriverPeriphMeasure>().Where( x => x.Driver.Id == driver )
                    .SelectList( list => list
                        .Select( Projections.SqlGroupProjection( "YEAR(MeasureDateLocal) As [Year]", "YEAR(MeasureDateLocal)", new[] { "YEAR" }, new IType[] { NHibernateUtil.Int32 } ) )
                        .Select( Projections.SqlGroupProjection( "MONTH(MeasureDateLocal) As [MONTH]", "MONTH(MeasureDateLocal)", new[] { "MONTH" }, new IType[] { NHibernateUtil.Int32 } ) )
                        .Select( Projections.SqlGroupProjection( "DAY(MeasureDateLocal) As [DAY]", "DAY(MeasureDateLocal)", new[] { "DAY" }, new IType[] { NHibernateUtil.Int32 } ) )
                        );

但我找不到将其设置为子查询的方法。

4

1 回答 1

2

目前只能使用 HQL。正如 Andrew Whitaker 提到的,NH 不支持选择子句中的子选择。但是,可以使用 in 表达式将 select 子句中的 subselect 转换为 from 子句中的 subselect。因此,对于分组,您必须从 subselect 中选择 max(id),但由于in子句中 SQL 的限制,您可以使用 subselect 仅返回一列。

但在 Criteria 和 QueryOver API 中,无法从 select 子句中排除分组字段(https://nhibernate.jira.com/browse/NH-1426

由于这两个问题,linq 无法做到这一点:https ://nhibernate.jira.com/browse/NH-3154和https://nhibernate.jira.com/browse/NH-3155

所以你有最后机会用 HQL 做到这一点:

var count = session.CreateQuery(
    @"select count(dm.Id) 
      from DriverPeriphMeasure dm 
      where dm.Id in (
          select max(dm1.Id) 
          from DriverPeriphMeasure dm1 
          where dm1.IdDriver = :? 
          group by date(dm1.MeasureDateLocal)
      )").UniqueResult();
于 2012-07-23T16:33:47.733 回答