views:

328

answers:

2

I have a criteria query that I am using to show pages of results. I also need to obtain the total count of all items. Rather than have two queries, one for paging the results and one for the count (since they are identical apart from the .AddOrder()

public ICriteria StandardQuery {
    get {
        return NHibernateSesssionManager.GetSession.CreateCriteria<Person>.AddOrder("OrderProperty", Order.Desc);
    }

public ICriteria CountQuery {
    get{
        return StandardQuery.SetProjection(Projections.Count("ID"));
    }

Obviously the CountQuery barfs with "Column "dbo.Person.ordercolumn" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause."

This makes sense, so basically I want to do something like this.

public ICriteria CountQuery {
    get{
        return StandardQuery.RemoveOrders().SetProjection(Projections.Count("ID"));
    }

Is there a way to do something like this? So that I am saved the "risk" of having two duplicate queries, one for paging and one for count. Clearly any change to either query needs to be mirrored on the other and this is risk that I do not like. What would you do?

+2  A: 

I'd do something like this:

private ICriteria BaseQuery {
    get {
     return NHibernateSesssionManager.GetSession().CreateCriteria<Person>();
    }
}

public ICriteria StandardQuery {
    get {
        return BaseQuery.AddOrder("OrderProperty", Order.Desc);
    }
}

public ICriteria CountQuery {
    get{
        return BaseQuery.SetProjection(Projections.Count("ID"));
    }
}
Mauricio Scheffer
+2  A: 

There's a method exactly for this. Unfortunately its a bit messy to use.

    private ICriteria NewCount
    {
        get
        {
            ICriteria countQuery = (ICriteria) StandardQuery.Clone();
            countQuery.ClearOrders();
            return countQuery.SetProjection(Projections.Count("ID"));
        }
    }

No idea why ClearOrders() returns void instead of ICriteria, but it works!

athleticwhiteguy
WOW the NHibernate guys really have thought of everything!! Shame I can't do "return StandardQuery.ClearOrders();" I wonder why they did it like that...
reach4thelasers