NHibernate选择复数和

NHibernate选择复数和,nhibernate,queryover,nhibernate-projections,Nhibernate,Queryover,Nhibernate Projections,我有一个实体: 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 我可以通过以下方式实现: QueryOver.Of<Entity>().Select

我有一个实体:

    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
我可以通过以下方式实现:

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

但我不想使用字符串。如何以其他方式实现它?

不幸的是,NHibernate没有内置的算术运算符。在此基础上,以下是一些选项:

  • 直接使用
    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?>()
    
    这基本上可以避免每次使用
    -
    函数时都重新定义它,而且更简洁

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

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

    非常感谢。你的解决方案对我的案子有效。但我想没有办法用不同的运算符来处理sum(例如sum(A-B+C))。这很奇怪,因为
    Query().Sum(x=>x.A+x.B+x.C)
    有效。不幸的是,我必须使用QueryOverWell,您可以定义一个
    +
    操作符,然后用对
    -
    操作符的调用嵌套它。但是,不太理想。
    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?>()