Linq to NHibernate:一次选择多个总和

时间:2011-08-31 16:46:00

标签: sql nhibernate linq-to-nhibernate

有没有办法使用Linq to NHibernate一次选择多个总和?

现在我有了

int? wordCount = (from translation in session.Query<TmTranslation>()
                  where translation.SatisfiesCondition
                  select translation.TranslationUnit)
                 .Sum(x => (int?)(x.WordCount + x.NumberCount)) ?? 0;

int? tagCount = (from translation in session.Query<TmTranslation>()
                 where translation.SatisfiesCondition
                 select translation.TranslationUnit)
                .Sum(x => (int?)(x.TagCount)) ?? 0;

int? characterCount = (from translation in session.Query<TmTranslation>()
                       where translation.SatisfiesCondition
                       select translation.TranslationUnit)
                      .Sum(x => (int?)(x.CharacterCount)) ?? 0;

生成三个不同的SQL查询。在SQL中我可以同时抓取它们三个,但有没有办法在Linq中对NHibernate执行此操作?

谢谢。

3 个答案:

答案 0 :(得分:1)

这应该有助于您开始使用QueryOver方式......

ResultDTO dtoAlias = null; //placeholder alias variable

var dto = session.OueryOver<TmTranslation>()
    .Where(x => x.SatisfiesCondition)
    //Change this to the actual type of Translation property
    .JoinQueryOver<Translation>(x => x.Translation)
    .SelectList(list => list
        //we can sum these columns individually to keep query simple,...add them together later
        .SelectSum(x => x.WordCount).WithAlias(() => dtoAlias.WordCountTotal)
        .SelectSum(x => x.NumberCount).WithAlias(() => dtoAlias.NumberCountTotal)
        //add more select sums to the select list
        )
    .TransformUsing(Transformers.AliasToBean<ResultDTO>())
    .SingleOrDefault<ResultDTO>();

答案 1 :(得分:1)

Select()调用中有多个聚合函数可以工作并导致发送到数据库的单个SQL命令。例如:

var result = session.Query<TmAssignment>()
                    .Select(a => new
                    {
                       Words = session.Query<TmTranslation>().Where(s => s.Assignment == a).Sum(u => (int?) u.WordCount) ?? 0,
                       Others = session.Query<TmTranslation>().Where(s => s.Assignment == a).Sum(u => (int?)(u.TagCount + u.NumberCount)) ?? 0,
                    }).ToList();

答案 2 :(得分:0)

我使用的可能更简单的解决方案是进行人工GroupBy,然后投影到匿名对象:

例如

session.Query<TmTranslation>()
  .Where(o => o.SatisfiesCondition)
  .Select(o => o.TranslationUnit)
  .GroupBy(o => 1)
  .Select(o => new 
   {
     WordCount = o.Sum(x => (int?)(x.WordCount + x.NumberCount)) ?? 0,
     TagCount = o.Sum(x => (int?)(x.TagCount)) ?? 0,
     CharacterCount = o.Sum(x => (int?)(x.CharacterCount)) ?? 0
   })
  .Single(); 

这也只产生一个SQL语句,并很好地减少了重复。