views:

44

answers:

2

If I have the following class structure what is the NH criteria to select a parent if one of it's children has a specific name?

 public class Child
 {
     public int Id { get; set; }
     public int Name { get; set; }
 }

 public class Parent
 {
     public int Id { get; set; }
     public IList<Child> Children { get; set; }
 }
A: 

What I did was to create a criteria query for the parent type, use the return to create a criteria query for the child type, and then add the specific conditions to the child type sub query.

public virtual IList<T> GetByChildCriteria(string childName,
   params ICriterion[] criterion)
{
     ICriteria criteria = NHibernateSession
     .CreateCriteria(persitentType)
     .CreateCriteria(childName);
     foreach (ICriterion criterium in criterion)
     {
         criteria.Add(criterium);
     }
     return criteria.List<T>();
}

Note: The NHibernateSession variable is of type ISession.

cmsjr
+2  A: 

I'd just create an alias to the collection and add restrictions.

var parentsWithKidName = session.CreateCriteria<Parent>()
    .CreateAlias("Children", "c", InnerJoin)
    .Add(Restrictions.Eq("c.Name", childName))
    .SetResultTransformer(Transformers.DistinctRootEntity()) 
    .List<Parent>();

This would result in

select p.* 
from parent p 
inner join child c on /* however it's mapped? */
where c.Name = ?

The distinct root entity transformer will process the result set and remove duplicated parents. They still come across the wire though.

dotjoe