代码之家  ›  专栏  ›  技术社区  ›  Carl

nHibernate聚合子查询

  •  2
  • Carl  · 技术社区  · 15 年前

    我有一个问题与NHibernate,我似乎无法找到一个简单的办法。

    我有以下数据库:

    游戏:ID,得分,匹配ID

    匹配:ID

    一场比赛由3场比赛组成。

    我想知道最大匹配分数是多少,所以下面的SQL可以做到这一点:

    select max(a.total) from 
      (select Match.ID, sum(Game.Score) as total 
         from Game inner join Match
         on Game.Match_ID = Match.ID
         group by Match.ID) a
    

    在NHibernate,这似乎有点棘手。显然,HQL不允许在FROM子句中使用子查询,因此我不能真正使用它。

    我很确定可以用ICriteria来完成,但我刚开始使用NH,所以我似乎还没弄清楚。我基本上要做的是:

    Session.CreateCriteria<Game>()
        .SetProjection(Projections.ProjectionList()
            .Add(Projections.GroupProperty("Match"))
            .Add(Projections.Sum("Score"))).List();
    

    在那之后,我已经玩过各种各样的分离式标准,但似乎只是在循环。

    2 回复  |  直到 15 年前
        1
  •  6
  •   Ahmet Recep Navruz    15 年前

    对于hql世界,一个查询就可以解决这个问题…

    var maxScore = session.CreateQuery(@"select sum(game.Score) 
                                         from Game game 
                                         group by game.Match
                                         order by sum(game.Score) desc")
                          .SetMaxResults(1)
                          .UniqueResult<long>();
    

    希望这有帮助。

    更新:对于标准世界,可能会有更好的结果转换,但这是可行的:)

    var max = (int)session.CreateCriteria<Game>("game")
        .SetProjection(Projections.ProjectionList()
                           .Add(Projections.GroupProperty("game.Match"))
                           .Add(Projections.Sum("game.Score"), "total"))
        .AddOrder(Order.Desc("total"))
        .SetMaxResults(1)
        .SetResultTransformer(Transformers.AliasToEntityMap)
        .UniqueResult<IDictionary>()["total"];
    
        2
  •  1
  •   reach4thelasers    15 年前

    实际上,我在SQL中是这样做的:

    select top 1 Match.ID, sum(Game.Score) as total 
         from Game inner join Match
         on Game.Match_ID = Match.ID
         group by Match.ID order by total desc
    

    group-by在criteria/hql中总是很棘手:因为group-by子句只能返回分组列和任何其他列的聚合。因此,不可能从group by子句返回整个实体,只返回您正在分组和聚合的ID。

    因此,我通常使用本机SQL进行分组查询,如下所示:

    ISQLQuery sqlQuery1 = NHibernateSessionManager.Instance.GetSession().CreateSQLQuery("select Match.ID, sum(Game.Score) as total from Game inner join Match on Game.Match_ID = Match.ID group by match.ID order by total desc");
    sqlQuery1.AddScalar("id", NHibernateUtil.Int32); //
    sqlQuery1.AddScalar("total", NHibernateUtil.Int32);
    sqlQuery1.SetMaxResults(1);    
    var result = sqlQuery1.List();