【问题标题】:NHibernate select complex sumNHibernate 选择复数和
【发布时间】:2016-12-26 15:38:58
【问题描述】:

我有一个实体:

    class Entity
    {
        public int A { get; set; }
        public int B { get; set; }
        public int C { get; set; }
    }

我想选择 (A-B-C) 的总和。所以我想像这样运行sql:

SELECT SUM(A-B-C) FROM Entity

我可以通过SqlProjection来实现:

QueryOver.Of<Entity>().Select(Projections.SqlProjection("SUM(A-B-C) AS total", new[] { "total" }, new IType[] { NHibernateUtil.Int32 }));

但我不想使用字符串。其他方式怎么实现?

【问题讨论】:

    标签: nhibernate queryover nhibernate-projections


    【解决方案1】:

    不幸的是,NHibernate 没有内置算术运算符。搭载this question and answer,这里有几个选项:

    1. 直接使用VarArgsSQLFunction

      var subtractFunction = new VarArgsSQLFunction(string.Empty, " - ", string.Empty);
      
      session.QueryOver<Entity>(() => entityAlias)
          .Select(
              Projections.Sum(
                  Projections.SqlFunction(
                      subtractFunction, NHibernateUtil.Int32,
                          Projections.Property(() => entityAlias.A),
                          Projections.Property(() => entityAlias.B),
                          Projections.Property(() => entityAlias.C)
                  )
              )
          )
          .SingleOrDefault<int?>()
      

      这是实现这一点最直接的方法,但也有几种方法可以修饰它。

    2. 创建自己的方言并注册-函数:

      public class MyDialect : MsSql2008Dialect
      {
          public MyDialect()
          {
              this.RegisterFunction("-", new VarArgsSQLFunction(string.Empty, " - ", string.Empty));
          }
      }
      
      session.QueryOver<Entity>(() => entityAlias)
          .Select(
              Projections.Sum(
                  Projections.SqlFunction(
                      "-", NHibernateUtil.Int32,
                          Projections.Property(() => entityAlias.A),
                          Projections.Property(() => entityAlias.B),
                          Projections.Property(() => entityAlias.C)
                  )
              )
          )
          .SingleOrDefault<int?>()
      

      这基本上可以让你避免每次使用-函数时都重新定义它,而且更简洁一些。

    3. 您可以更进一步,将投影重构为扩展方法:

      public static class CustomProjections
      {
          public static IProjection Subtract(IType type, params IProjection[] projections)
          {
              return Projections.SqlFunction("-", type, projections);
          }
      }
      
      session.QueryOver<Entity>(() => entityAlias)
          .Select(
              Projections.Sum(
                  CustomProjections.Subtract(
                      NHibernateUtil.Int32,
                      Projections.Property(() => entityAlias.A),
                      Projections.Property(() => entityAlias.B),
                      Projections.Property(() => entityAlias.C)
                  )
              )
          )
          .SingleOrDefault<int?>()
      

    所有这些都会生成以下 SQL:

    SELECT
        sum(this_.A - this_.B - this_.C) as y0_ 
    FROM
        Entity this_
    

    【讨论】:

    • 谢谢。您的解决方案适用于我的情况。但我想没有办法用不同的运算符处理求和(例如 SUM(A-B+C))。这很奇怪,因为Query&lt;Entity&gt;().Sum(x=&gt;x.A+x.B+x.C) 有效。不幸的是,我必须使用 QueryOver
    • 好吧,你可以定义一个+ 操作符,然后通过调用- 来嵌套它。但是,是的,并不理想。
    猜你喜欢
    • 2012-04-07
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多