NHibernate中子查询的总和

时间:2014-05-08 09:43:31

标签: sql nhibernate

我正在使用NHibernate 3.3.1.4000。

这就是我想要实现的目标:

SELECT sum(tr_time)
FROM (SELECT seg.translation_time as tr_time
      FROM "TRANSLATION" seg
      WHERE seg.translation_time > 0 and seg.fk_id_language = 34
      ORDER BY seg.translation_time ASC
      LIMIT 1000) as subquery

使用LINQ to NHibernate的最简单方法是使用NotSupportedException

失败
session.Query<Translation>()
       .Where(s => s.Language == language && s.TranslationTime > 0)
       .OrderBy(s => s.TranslationTime)
       .Take(1000)
       .Select(s => s.TranslationTime)
       .Sum(s => s);

我能够生成这个SQL:

SELECT sum(this_.translation_time) as y0_
FROM "TRANSLATION" this_
WHERE this_.id in (SELECT this_0_.id as y0_
                   FROM "TRANSLATION" this_0_
                   WHERE  this_0_.fk_id_language = 34
                       and this_0_.translation_time > 0                       
                   ORDER  BY this_0_.translation_time asc
                   LIMIT 1000)

使用以下查询:

session.QueryOver<Translation>(() => translationAlias)
       .WithSubquery.WhereProperty(s => s.Id)
                    .In(QueryOver.Of<Translation>(() => translationSubAlias)
                                 .Where(s => s.Language == language)
                                 .Where(s => s.TranslationTime > 0)
                                 .Select(s => s.Id)
                                 .OrderBy(s => s.TranslationTime).Asc
                                 .Take(1000))
       .Select(Projections.ProjectionList()
                          .Add(Projections.Sum(Projections.Property(() => translationAlias.TranslationTime))))
       .FutureValue<Int32>();

然而,这显然不理想,因为WHERE ... IN条款不是必需的。

我尝试过像

这样的事情
session.QueryOver<Translation>(() => translationAlias)
       .Select(Projections.ProjectionList()
          .Add(Projections.Sum(
                  Projections.Alias(
                     Projections.SubQuery(
                         QueryOver.Of<Translation>(() => translationSubAlias)
                                  .Where(() => translationSubAlias.Language == language)
                                  .Where(() => translationSubAlias2.TranslationTime > 0)
                                  .Select(Projections.Property("TranslationTime"))), "tr_time"))))
       .FutureValue<Int32>()

但它生成了这个SQL:

SELECT sum((SELECT this_0_.translation_time as y0_
FROM "TRANSLATION" this_0_
WHERE this_0_.fk_id_language = 34 and this_0_.translation_time > 0)) as y0_
FROM "TRANSLATION" this_
数据库服务器拒绝的

,并显示以下错误消息:用作表达式的子查询返回的多行

我并不关心我最终会使用哪种方法(LINQ,QueryOver,Criteria API),只要它允许将来查询。

1 个答案:

答案 0 :(得分:0)

任何机会都没有返回任何值?如果是这种情况,您需要使TranslationTime可以为空:

session.Query<Translation>()
   .Where(s => s.Language == language && s.TranslationTime > 0)
   .OrderBy(s => s.TranslationTime)
   .Take(1000)
   .Select(s => s.TranslationTime)
   .Sum(s => (int?) s);

注意&#34; int?&#34; cast,假设TranslationTime的类型为int。