1

私はエンティティを持っています:

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

(ABC)の合計を選択したい。だから私はこのように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 }));

しかし、私は文字列を使いたくありません。他の方法でどのように行うことができますか?

4

1 に答える 1

2

残念ながら、NHibernate には算術演算子が組み込まれていません。この質問と回答に便乗して、ここにいくつかのオプションがあります:

  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_
于 2016-12-28T02:12:05.983 に答える