7

基準クエリから行数を取得する必要があり、基準は射影によってグループ化されました。(ページングを機能させる必要があります)

例えば

projectionList.Add(Projections.GroupProperty("Col1"), "col1")
              .Add(Projections.CountDistinct("Col2"), "Count");

多くの基準があるため、CreateSQL を避ける必要があり、制限などが複雑です。

サブ基準(分離)を実行できますselect count(*) from ..か?方法がわかりませんか?

編集:基準からSQLを取得し、それを修正して解決しました! 条件からの GetSql

4

4 に答える 4

0

既成概念にとらわれず、NHiberate からクエリの複雑さを取り除きます。データベースでクエリのビューを作成し、ビューのマッピングを作成できます。

于 2012-05-21T13:43:21.863 に答える
0

あなたが何を望んでいるのか完全にはわかりませんが、次のようなものがうまくいくはずです(あなたの質問を正しく理解していれば):

var subQuery = DetachedCriteria.For<SomeClass>()
   .Where(... add your conditions here ...);

var count = Session.CreateCriteria<SomeClass>()
   .Where(Property.ForName("Col1").In(
      CriteriaTransformer.Clone(subQuery).SetProjection(Projections.Property("Col1"))
   .SetProjection(Projections.Count())
   .FutureValue<int>();

var results = subQuery.GetExecutableCriteria(Session)
            .SetProjection(Projections.GroupProperty("Col1"), "col1"),
                           Projections.CountDistinct("Col2"), "Count")
            ).List<object[]>();
于 2012-05-21T12:06:37.983 に答える
0

Java バージョン (Hibernate) でこの問題を解決しました。問題は、RowProjection 関数が次のようなものであることです。

count(*) 

これは集計関数です。したがって、「group by」プロパティを作成すると、結果はグループ化された行のリストになり、行ごとにグループの合計数が得られます。

私にとって、Oracleデータベースを使用して機能させるために、関数カウント(*)を作成する代わりに、関数が

count(count(*)) 

および group by 句のプロパティは、select ... from ステートメントに記述されていません。それを行うには、それほど単純ではありません。問題は、適切なSQLを作成するためにすべてのスタックを提供する必要があることです.Javaバージョンでは、2つのクラスをサブクラス化する必要があります:SimpleProjection ProjectionList

その後、私のクエリは次のように生成されました:

select count(*), col1, col2 from table1 group by col1, col2

なる

select count(count(*)) from table1 group by col1, col2

結果は、によって与えられた合計行です

select col1, col2 from table1 group by col1, col2

(ページネーションシステムで使用可能)

あなたに役立つ場合は、ここにクラスのJavaバージョンを投稿します。

public class CustomProjectionList extends ProjectionList {

    private static final long serialVersionUID = 5762155180392132152L;


    @Override
    public ProjectionList create() {
        return new CustomProjectionList();
    }

    public static ProjectionList getNewCustomProjectionList() {
        return new CustomProjectionList();
    }

    @Override
    public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) throws HibernateException {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < getLength(); i++) {
            Projection proj = getProjection(i);
            String sqlString = proj.toSqlString(criteria, loc, criteriaQuery);
            buf.append(sqlString);
            loc += getColumnAliases(loc, criteria, criteriaQuery, proj).length;
            if (i < (getLength() - 1) && sqlString != null && sqlString.length() > 0)
                buf.append(", ");
        }
        return buf.toString();
    }

    private static String[] getColumnAliases(int loc, Criteria criteria, CriteriaQuery criteriaQuery, Projection projection) {
        return projection instanceof EnhancedProjection ?
                ( ( EnhancedProjection ) projection ).getColumnAliases( loc, criteria, criteriaQuery ) :
                projection.getColumnAliases( loc );
    }


}

public class CustomPropertyProjection extends SimpleProjection {


    private static final long serialVersionUID = -5206671448535977079L;

    private String propertyName;
    private boolean grouped;


    @Override
    public String[] getColumnAliases(int loc, Criteria criteria, CriteriaQuery criteriaQuery) {
        return new String[0];
    }

    @Override
    public String[] getColumnAliases(int loc) {
        return new String[0];
    }

    @Override
    public int getColumnCount(Criteria criteria, CriteriaQuery criteriaQuery) {
        return 0;
    }


    @Override
    public String[] getAliases() {
        return new String[0];
    }

    public CustomPropertyProjection(String prop, boolean grouped) {
        this.propertyName = prop;
        this.grouped = grouped;
    }

    protected CustomPropertyProjection(String prop) {
        this(prop, false);
    }

    public String getPropertyName() {
        return propertyName;
    }

    public String toString() {
        return propertyName;
    }

    public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
    throws HibernateException {
        return new Type[0];
    }

    public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
    throws HibernateException {

        return "";
    }

    public boolean isGrouped() {
        return grouped;
    }

    public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
    throws HibernateException {
        if (!grouped) {
            return super.toGroupSqlString(criteria, criteriaQuery);
        }
        else {
            return StringHelper.join( ", ", criteriaQuery.getColumns( propertyName, criteria ) );
        }
    }

}

public class CustomRowCountProjection extends SimpleProjection {
    /**
     * 
     */
    private static final long serialVersionUID = -7886296860233977609L;


    @SuppressWarnings("rawtypes")
    private static List ARGS = java.util.Collections.singletonList( "*" );

    public CustomRowCountProjection() {
        super();
    }


    public String toString() {
        return "count(count(*))";
    }

    public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
        return new Type[] {
                getFunction( criteriaQuery ).getReturnType( null, criteriaQuery.getFactory() )
        };
    }

    public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException {
        SQLFunction countSql = getFunction( criteriaQuery );
        String sqlString = countSql.toString() + "(" +  countSql.render( null, ARGS, criteriaQuery.getFactory() ) + ") as y" + position + '_';
        return sqlString;
    }

    protected SQLFunction getFunction(CriteriaQuery criteriaQuery) {
        SQLFunction function = criteriaQuery.getFactory()
                .getSqlFunctionRegistry()
                .findSQLFunction( "count" );
        if ( function == null ) {
            throw new HibernateException( "Unable to locate count function mapping" );
        }
        return function;
    }
}

この助けを願っています。

于 2012-05-21T16:11:55.107 に答える
0

これは、NH Multi Queries を使用して実行できると思います。

http://ayende.com/blog/3979/nhibernate-futures例は、クエリを実行し、データベースへの 1 回のラウンドトリップでそのクエリの結果数を取得する方法を示しています。

nhibernate 2.0 Efficient Data Paging DataList コントロールと ObjectDataSourceでは、データベースへの 1 回のラウンドトリップで結果ページと合計レコード数を取得します。

また、データベース固有のものと@@rowcount同様に、SQLクエリを変更せずにNHで純粋な値を読み取ることができるとは思えません。@@rowcount

あなたのケースでは、クエリやアプローチを単純化しない限り、基準ソリューションから GetSqlを回避することはできないと思います。これも試してみる価値はあるのではないでしょうか。

コードのより大きな部分を投稿できれば、おそらく誰かがこれを理解できるでしょう。

于 2012-05-15T21:50:22.373 に答える