NHibernate,当条件具有分组依据时获取行计数
我需要从一个criteria查询中获得行数,然后根据投影对criteria进行分组。(需要让寻呼开始工作) 例如 我需要避免CreateSQL,因为我有很多标准。。限制条件等都很复杂 您是否可以执行一个次标准(分离),然后从..中选择计数(*)?不知道怎么做NHibernate,当条件具有分组依据时获取行计数,nhibernate,criteria,Nhibernate,Criteria,我需要从一个criteria查询中获得行数,然后根据投影对criteria进行分组。(需要让寻呼开始工作) 例如 我需要避免CreateSQL,因为我有很多标准。。限制条件等都很复杂 您是否可以执行一个次标准(分离),然后从..中选择计数(*)?不知道怎么做 编辑:我通过从标准中获取sql,然后修改它来解决它,使它现在可以工作 我认为这可以通过使用NH多重查询来实现 下面是一些关于它的内容:这个示例展示了如何运行查询并在数据库的一次往返中获得该查询的结果计数 这是一个很好的答案,听起来与您想要实
编辑:我通过从标准中获取sql,然后修改它来解决它,使它现在可以工作 我认为这可以通过使用NH多重查询来实现 下面是一些关于它的内容:这个示例展示了如何运行查询并在数据库的一次往返中获得该查询的结果计数 这是一个很好的答案,听起来与您想要实现的类似:在这个答案中,他们在一次到数据库的往返中获得结果页和总记录数 另外,我怀疑是否可以在不更改sql查询的情况下使用NH读取纯
@@rowcount
值,因为@@rowcount
是特定于数据库的内容
我的假设是,对于您的情况,除非您简化查询或方法,否则不可能避免解决方案。也许这也值得一试
如果您可以发布更大的代码块,可能有人会发现这一点。不完全确定您想要什么,但类似的内容应该可以工作(如果我正确理解您的问题):
var subQuery=DetachedCriteria.For()
.其中(…在此处添加您的条件…);
var count=Session.CreateCriteria()
.Where(Property.ForName(“Col1”).In(
CriteriaTransformer.Clone(子查询).SetProjection(Projections.Property(“Col1”))
.SetProjection(Projections.Count())
.未来价值();
var results=subQuery.GetExecutableCriteria(会话)
.SetProjection(Projections.GroupProperty(“Col1”),“Col1”),
预测。CountDistinct(“Col2”),“Count”)
).List();
只需跳出框框思考一下,从NHiberate中消除查询复杂性。您可以在数据库中为查询创建一个视图,然后为该视图创建一个映射。我已经在java版本(Hibernate)上解决了这个问题。问题是RowProjection函数类似于:
count(*)
这是一个聚合函数:因此,如果您创建一个“groupby”属性,您的结果是一个分组行的列表,并且对于每一行,您都有组的总计数
对于我来说,为了使oracle数据库正常工作,我创建了一个自定义投影,该投影不是创建函数count(*),而是
count(count(*))
并且GROUPBY子句中的属性未写入select。。。来自声明。要做到这一点并不是那么简单,问题是您必须提供所有堆栈来创建正确的sql,因此,对于java版本,我必须使用Subasse 2类:
单投影
放映员
之后,我的查询生成为:
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;
}
}
公共类CustomProjectionList扩展了ProjectionList{
私有静态最终长serialVersionUID=5762155180392132152L;
@凌驾
公共投影列表create(){
返回新的CustomProjectionList();
}
公共静态ProjectionList getNewCustomProjectionList(){
返回新的CustomProjectionList();
}
@凌驾
公共字符串toSqlString(Criteria、int-loc、CriteriaQuery-CriteriaQuery)抛出HibernateException{
StringBuffer buf=新的StringBuffer();
对于(int i=0;i0)
buf.追加(“,”);
}
返回buf.toString();
}
私有静态字符串[]GetColumnAlias(int-loc、条件、标准查询、标准查询、投影){
返回增强投影的投影实例?
((EnhancedProjection)投影)。GetColumnAlias(loc、criteria、criteriaQuery):
projection.getColumnAlias(loc);
}
}
公共类CustomPropertyProjection扩展了SimpleProjection{
私有静态最终长serialVersionUID=-5206671448535977079L;
私有字符串propertyName;
私有布尔分组;
@凌驾
公共字符串[]GetColumnAlias(int-loc、Criteria-Criteria、CriteriaQuery-CriteriaQuery){
返回新字符串[0];
}
@凌驾
公共字符串[]GetColumnAlias(int-loc){
返回新字符串[0];
}
@凌驾
public int getColumnCount(条件、条件查询、条件查询){
返回0;
}
@凌驾
公共字符串[]getAlias(){
返回新字符串[0];
}
公共CustomPropertyProjection(字符串属性,布尔分组){
this.propertyName=prop;
this.grouped=grouped;
}
受保护的CustomPropertyProjection(字符串属性){
这个(道具,假);
}
公共字符串getPropertyName(){
返回propertyName;
}
公共字符串toString(){
返回propertyName;
}
公共类型[]获取类型(条件,条件查询,条件查询)
抛出冬眠异常{
返回新类型[0];
}
公共字符串toSqlString(条件、int位置、CriteriaQuery-CriteriaQuery)
抛出冬眠异常{
返回“”;
}
公共布尔值(){
分组返回;
}
public String toGroupSqlString(Criteria、CriteriaQuery、CriteriaQuery)
抛出冬眠异常{
如果(!分组){
返回super.toGrou
select col1, col2 from table1 group by col1, col2
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;
}
}