For entity ParentEntity
with a collection of type ChildEntity
which contains an Order
property of type int, how can the parent entity be retrieved with the child collection sorted by Order
specifically through the use of the Criteria API as discussed in section 12.4 of the NHibernate docs here?
I've tried using code similar to the following:
public ParentEntity GetById(int id)
{
ICriteria criteria = _sessionFactory.GetCurrentSession().CreateCriteria(typeof (ParentEntity));
criteria.Add(Restrictions.Eq("Id", id))
.CreateCriteria("Children")
.AddOrder(Order.Desc("Order"));
return (ParentEntity) criteria.List()[0];
}
Unfortunately, this code produces 2 SELECT
statements. The first select contains an order by
which sorts the associated columns retrieved, but the second does not and this seems to be the one from which the collection is being populated.
Note, I've tried configuring NHibernate to do an outer join fetch without which works as expected without the criteria. That is, it produces two queries without the outer join configured, but only one with the outer join configured. The addition of the added criteria seems to cause an extra query regardless.
Please limit answers to how this can be done using the criteria API or explanations as to why this wouldn't work. I'm aware the sorting can be done through the mapping, but I'm trying to understand what specifically the issue is using the criteria method.
==== EDIT ====
The following is the model and mappings:
public class ParentEntity
{
public virtual int Id { get; private set; }
public virtual IList<ChildEntity> Children { get; set; }
public ParentEntity()
{
Children = new List<ChildEntity>();
}
}
public class ChildEntity
{
public virtual int Id { get; private set; }
public virtual ParentEntity Parent { get; private set; }
public virtual int Order { get; private set; }
protected ChildEntity()
{
}
public ChildEntity(int order)
{
Order = order;
}
}
public class ParentEntityMap : ClassMap<ParentEntity>
{
public ParentEntityMap()
{
WithTable("Parent");
Id(p => p.Id);
HasMany(p => p.Children)
.KeyColumnNames.Add("Parent_Id")
.Cascade.All();
}
}
public class ChildEntityMap : ClassMap<ChildEntity>
{
public ChildEntityMap()
{
WithTable("Child");
Id(c => c.Id);
Map(c => c.Order, "[Order]");
References(c => c.Parent, "Parent_Id")
.Cascade.All();
}
}
==== EDIT 2 ====
As an update, after adding Not.LazyLoad() to the Parent only a single SELECT
is generated, however, the results are still unsorted.