使用Linq(nHibernate)用Counts执行Case语句

时间:2011-03-24 16:42:36

标签: linq nhibernate count case queryover

我确信这是一个人已经做了几次房子,但我从来没有找到解决方案......

因此可以使用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中有一些新东西可以做到这一点,甚至使用查询?

感谢

2 个答案:

答案 0 :(得分: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。第一个计算Tutorials中的行,其中IsWithdrawn = true,第二个计算所有行。然后将两个分离的QueryOvers用作带有Projection(SelectList)的普通QueryOver中的SubQueries。

这是生成的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_;

答案 1 :(得分: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

(我不确定COUNT是否可行,我确定SUM会这样做)

这是一个也应该起作用的LINQ版本:

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

您可以将Projections.Conditional与Criteria或QueryOver一起使用,但这样做更有效。