2011-03-24 31 views
0

Case語句我敢肯定,這是一個做了房子了幾次,但我從來沒有找到一個解決方案...使用LINQ(NHibernate的),以執行與計數

所以是有可能這樣做像這樣使用NHibernate 3最好的Linq:

SELECT 
COUNT(CASE WHEN IsWithdrawn = 1 THEN 1 END) AS WithdrawnCount, 
COUNT(CASE WHEN IsWithdrawn = 0 THEN 1 END) AS ViewAllCount 
FROM Tutorials 

我敢肯定這是不是可能的,最好的辦法是選擇只是在這種情況下,SQL ...但也許有一些新的nHibernate 3.1可以做到這一點,甚至使用queryover?

感謝

回答

2

您可以使用HQL,這幾乎是相同的SQL做到這一點:

SELECT 
SUM(CASE WHEN IsWithdrawn = 1 THEN 1 ELSE 0 END) AS WithdrawnCount, 
SUM(CASE WHEN IsWithdrawn = 0 THEN 1 ELSE 0 END) AS ViewAllCount 
FROM Tutorials 

(我不知道如果計會工作我敢肯定,SUM一樣)

這裏有一個LINQ版本,應太:

session.Query<Tutorial>() 
     .GroupBy(x => x.IsWithdrawn) 
     .Select(x => new { x.Key, Count = x.Count() }) 

您可以使用Projections.Conditional與Criteria或QueryOver,但它更多的工作。

2

您可以QueryOver得到期望的結果,但它會比較慢,由於子查詢。

var sums = repo.Session.QueryOver<Tutorials>() 
    .SelectList(list => list 
     .SelectSubQuery<Tutorials>(NHibernate.Criterion.QueryOver.Of<Tutorials>() 
      .Where(t => t.IsWithdrawn) 
      .ToRowCountQuery()) 
     .SelectSubQuery<Tutorials>(NHibernate.Criterion.QueryOver.Of<Tutorials>() 
      .ToRowCountQuery()) 
    ) 
    .Take(1) // we want only one row in our result. In SQL I would use " from dummy". 
    .List<object[]>(); 

說明:

我用兩個分離QueryOvers。第一個統計教程中的行,其中IsWithdrawn = true,第二個統計所有行。這兩個分離的QueryOver隨後用作具有投影(SelectList)的普通QueryOver中的子查詢。

這裏是生成的SQL:

SELECT TOP (1) 
(SELECT count(*) as y0_ FROM [Tutorials] this_0_ 
WHERE this_0_.IsWithdrawn = True) as y0_, 
(SELECT count(*) as y0_ FROM [Tutorials] this_0_) as y1_ 
FROM [Tutorials] this_; 
+0

通過sql profiler運行這個子查詢使用case語句的區別是61%和39%。令人遺憾的是,儘管上述解決方案可行,但使用性能成本太高。如果查詢不會經常出現,那麼它是一個不錯的選擇;) – Jay 2011-03-25 11:44:08