【问题标题】:Linq to NHibernate: Select multiple sums at onceLinq to NHibernate:一次选择多个总和
【发布时间】:2011-08-31 16:46:00
【问题描述】:

有没有办法使用 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 to NHibernate 中做到这一点?

谢谢。

【问题讨论】:

  • 您是想要一次查询中的 3 个总和还是一次将所有 3 个查询发送到服务器?无论哪种方式,QueryOver 都绝对可以实现。
  • @dotjoe 那太好了,请问您有一些示例吗?我使用QueryOver写了一些查询,但是当我需要更复杂的东西时,我通常会发现它非常复杂,官方文档也没有太大帮助。
  • @dotjoe 为了回答你的问题,我打算在一个查询中得到所有 3 个总和。

标签: sql nhibernate linq-to-nhibernate


【解决方案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>();

【讨论】:

    【解决方案2】:

    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();
    

    【讨论】:

    • 很高兴看到您的解决方案
    • Soooo... 你的答案是什么?我以前从未投票过,但这不是一个有用的答案。
    • @twoflower,感谢您的更新。对于我正在处理的查询,您给了我一些考虑。你有没有分组的运气?
    • @mcfea 分组似乎在 NHibernate 的 LINQ 提供程序中运行良好。你有什么特别的问题吗?
    • @twoflower,确实分组在 NHibernate 的 LINQ 提供程序中编译得很好,但是,条件选择不能。它基本上只返回一个行数,我已经退回到聚合的 QueryOver 语法。我对最新版本的 Nhibernate 抱有希望,但看起来他们并没有解决相关的问题。如果你能解决这个人的问题,你也会解决我的问题:stackoverflow.com/questions/15015662/…
    【解决方案3】:

    我使用的一个可能更简单的解决方案是做一个人工 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 语句并很好地减少了重复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-08
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      • 2011-04-20
      相关资源
      最近更新 更多