2012-07-21 101 views
0

我正在使用nHibernate 3.3。我想這樣執行SQL:nHibernate在現有查詢中計數(*)

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

但我不能找到一種方法將它設置爲子查詢。

+0

任何方式,你可以重寫這個沒有內部'select'? QueryOver不擅長從任意表格表達式中進行選擇... – 2012-07-21 15:43:07

+0

我很害怕我無法刪除內部選擇:我需要對分組數據進行計數。 – ZmorzynskiK 2012-07-21 18:00:54

+0

QueryOver不支持from子句中的表達式。 Linq沒有這個限制。 – Firo 2012-07-23 10:03:23

回答

2

目前只能使用HQL進行操作。正如Andrew Whitaker所提到的,NH不支持select clasue中的子選擇。但是可以將select子句中的子查詢轉換爲from子句中的子查詢。因此,對於分組,您必須從subselect中選擇max(id),但作爲in子句中SQL的限制,您可以使用subselect返回僅一列。

但在標準和QueryOver API,不可能排除在SELECT子句(https://nhibernate.jira.com/browse/NH-1426

分組字段而這是不可能通過LINQ做,因爲這兩個問題:https://nhibernate.jira.com/browse/NH-3154https://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(); 
+0

非常感謝你的解釋。不幸的是,這種情況不適用於nhibernate。我想知道它在EF4/EF5中的外觀?也許是時候從nhibernate切換到EF ... 無論如何,您的HQL解決方案比我發佈的SQL解決方案更好嗎?我必須承認,在SQL執行計劃中,它看起來比我的複雜一點。 – ZmorzynskiK 2012-07-23 19:50:58

+0

我建議你使用SQL作爲這個HQL只是一個破解。 – hazzik 2012-07-23 21:56:46

+0

謝謝,會做到這一點。 – ZmorzynskiK 2012-07-24 21:36:57