0

我敢肯定这是一个做过几次房子的人,但我从来没有找到解决办法......

那么是否有可能使用 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?

谢谢

4

2 回答 2

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[]>();

解释:

我使用两个分离的 QueryOver。第一个计算教程中 IsWithdrawn = true 的行,第二个计算所有行。然后将两个分离的 QueryOver 用作带有 Projection (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_;
于 2011-03-24T22:33:29.710 回答
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.ConditionalCriteria 或 QueryOver,但它的工作量更大。

于 2011-03-26T14:48:11.040 回答