t-sql - linq to nhibernate 中的条件行计数不起作用

标签 t-sql nhibernate linq-to-nhibernate nhibernate-3

我想将以下简单的 sql 查询转换为 Linq to NHibernate:

SELECT NewsId 
     ,sum(n.UserHits) as 'HitsNumber'
     ,sum(CASE WHEN n.UserHits > 0 THEN 1 ELSE 0 END) as 'VisitorsNumber'
FROM UserNews n
GROUP BY n.NewsId

我的简化 UserNews 类:

public class AktualnosciUzytkownik
{
    public virtual int UserNewsId { get; set; }
    public virtual int UserHits { get; set; }        
    public virtual User User { get; set; }  // UserId key in db table
    public virtual News News { get; set; }  // NewsId key in db table
}

我编写了以下 linq 查询:

var hitsPerNews = (from n in Session.Query<UserNews>() 
                   group n by n.News.NewsId into g
                   select new { NewsId = g.Key, HitsNumber = g.Sum(x => x.UserHits), 
                   VisitorsNumber = g.Count(x => x.UserHits > 0) }).ToList();

但是生成的 sql 只是忽略我的 x => x.UserHits > 0 语句并进行不必要的“左外连接”:

SELECT   news1_.NewsId               AS col_0_0_,
         CAST(SUM(news0_.UserHits) AS INT) AS col_1_0_,
         CAST(COUNT(*) AS             INT) AS col_2_0_
FROM     UserNews news0_
         LEFT OUTER JOIN News news1_
         ON       news0_.NewsId=news1_.NewsId
GROUP BY news1_.NewsId

如何修复或解决此问题?也许使用 QueryOver 语法可以做得更好?

最佳答案

我终于找到了问题的答案,我的解决方案基于 this question 的答案:

我的 QueryOver 代码(我仍然不知道如何在 Linq to NHibernate 中执行此操作):

UserHitsDto adDtoAlias = null;

var userHits = Session.QueryOver<UserNews>()
    .Select(Projections.Group<UserNews>(c => c.News.NewsId)
                                   .WithAlias(() => adDtoAlias.NewsId),
            Projections.Sum<UserNews>(x => x.UserHits)
                                   .WithAlias(() => adDtoAlias.HitsNumber),
            Projections.Sum(Projections.Conditional(
                Restrictions.Where<UserNews>(f => f.UserHits > 0),
                Projections.Constant(1),
                Projections.Constant(0)
            )).WithAlias(() => adDtoAlias.VisitorsNumber)
           )
    .TransformUsing(Transformers.AliasToBean<UserHitsDto>())
    .List<UserHitsDto>();

它生成以下 tsql:

SELECT   this_.NewsId  AS y0_,
         SUM(this_.UserHits) AS y1_,
         SUM((
         CASE
                  WHEN this_.UserHits > @p0
                  THEN @p1
                  ELSE @p2
         END)) AS y2_
FROM     UserNews this_
GROUP BY this_.NewsId

其中@p0 = 0、@p1 = 1、@p2 = 0

关于t-sql - linq to nhibernate 中的条件行计数不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9924418/

相关文章:

SQL Server窗口函数: can you do a ROW BETWEEN type construct?

sql-server - 更新后使用存储过程插入到同一个表中

c# - Fluent NHibernate 和好友关系

NHibernate 3.2 - MsSqlCeDialect : Dialect does not support variable limits

c# - 调用DacService.Deploy后如何取消和回滚升级包?

T-SQL - 如何在 xml 对象上使用 group by

.net - 存储库本身通常不经过测试?

sql-server-2008 - NHibernate LinqToHqlGenerator for SQL Server 2008 全文索引 'Containing' 关键字

c# - NHibernate OrderByDescending 抛出异常 `A recognition error occurred`

c# - Linq to nhibernate - 其中集合包含具有 id 的对象