我正在使用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),只要它允许将来查询。
答案 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。