Tim Scott's Blog

June 14, 2007

Ordering Computed Fields In ActiveRecord With ICriteria

Filed under: Active Record, C#, Castle Project — Tim Scott @ 11:48 pm

If you use ActiveRecord and ICriteria to fetch collections, this probably looks familiar:

DetachedCriteria criteria = DetachedCriteria.For(typeof(TaskEstimate));
...
criteria.AddOrder(Order.Asc("OptimisticHours"));
IList<TaskEstimate> estimates = TaskEstimate.FindAll(criteria);

The criteria object tells the FindAll method to sort the results ascending by the persisted property, “OptimisticHours.” But let’s say you have another persisted property “PessimisticHours,” and you want to sort by the difference between the optimistic and pessimistic estimates. That is to say, you want to sort by a computed value instead of a persisted property. Here’s how:

First you add the following to the TaskEstimate class:

private int _estimateDelta;
[Property(Formula = "PessimisticHours - OptimisticHours")]
public int EstimateDelta
{
    get { return _estimateDelta; }
    set { _estimateDelta= value; }
}

Then you can do this:

criteria.AddOrder(Order.Asc("EstimateDelta"));
IList<TaskEstimate> estimates = TaskEstimate.FindAll(criteria);

What’s happening here is that ActiveRecord is providing us access to the NHibernate mapping feature that allows you to define a property with a formula attribute.

4 Comments »

  1. This is great! Anyone know how to do this via NHibernate mapping without ActiveRecord?

    Comment by Nathan — January 9, 2008 @ 7:22 pm

  2. You do it in your map. I think it would be something like this:

    <property name="EstimateDelta" formula="PessimisticHours - OptimisticHours">

    …where PessimisticHours and OptimisticHours are also mapped elements.

    Comment by Tim Scott — January 9, 2008 @ 7:29 pm

  3. Yes, you do it in the mapping file, but I don’t think that *Hours have to be mapped. That’s the point of formula property :)

    Comment by Tom — January 29, 2008 @ 7:57 pm

  4. Why this error: “‘NHibernate.Mapping.Property’ is not an attribute class…” ?

    using NHibernate.Mapping;

    private string _NumeroFormatado;
    [Property(Formula = "Numero - Nome")]
    public virtual string NumeroFormatado
    {
    get { return _NumeroFormatado; }
    set { _NumeroFormatado = value; }
    }

    “Numero” and “Nome” are mapping properties from columns in table.

    Thanks.

    Comment by Richardson — July 18, 2008 @ 7:11 pm


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.