Thursday, May 5, 2011

Sorting linked collection in Nhibernate query

This is partly related to this.
I'd like to find a way to sort of a linked (HasMany) collection result directly in the Nhibernate query.

 ICriteria criteria = Session.CreateCriteria(typeof(PortalPage));
 criteria.CreateAlias("PartialViews", "vc");
 criteria.AddOrder(Order.Asc("vc.ColumnNumber"));
 criteria.Add(Property.ForName("Url").Eq(pageUrl));
 return criteria.UniqueResult<PortalPage>();

Correcly generates a select with the ORDER BY but the result in the linked collection is not ordered.

I'd like to avoid sorting the collection after the result is returned (like using linq to objects) is this possible?

UPDATE: As Steve suggested the problem can be solved by hard coding the order attribute in the mapping like:

HasMany(x => x.PartialViews).KeyColumnNames.Add("PageId").AsBag().SetAttribute("order-by", "ColumnNumber");
From stackoverflow
  • Have you specified the collection as a list type rather than a bag or a set? If you make sure to use a list mapping type and specify an index column for the list mapping everything should be taken care of for you.

    See the docs here, and there's some more info here too, although that second one is an older post so watch out for things that may have changed.

    Here's a simple list collection mapping example:

    <list name="Images table="Images">
      <key column="Id"/>
      <index column="Position"/>
      <element type="String" column="FileName"/>
    </list>
    

    The fluent mapping for this example would be something like this:

    HasMany(x => x.Images).AsList(x => x.WithColumn("Position"));
    
    Ronnie : Steve, if I understand this would force me to "hard code" the sort order. It is possible to get some kind of dynamic result with Linq2Nhibernate or other way? If not how would you express the same mapping in fluent nhibernate?
    Steve Willcock : Ronnie, I'm not sure about getting a dynamic result without sorting after the collection is returned using the OrderBy method. I suspect there's no way to do it reliably and that's due to the nature of child collections in a DDD object model - unless the child collection has an inherent sort order (e.g. a List rather than a Set or Bag) then it just doesn't make much sense from a modelling perspective to allow you to specify an order when retrieving the data. I'd have to check the Fluent syntax for a list mapping - I'll update the answer when I find that out!

0 comments:

Post a Comment