tags:

views:

436

answers:

1

I have a parent/child relationship mapped with a many-to-many set.

public class Parent
{
    public ISet<Child> Children { get; set; }
}

public class Child {}

public class ParentMap : ClassMap<Parent>
{
    HasManyToMany(x => x.Children)
        .AsSet();
}

How can I write a query to select all of the parents that contain a given child? I would have guessed that it would be something like this, but this API does not exist:

Session.CreateCriteria<Parent>()
   .Add(Expression.Contains("Children", child)
   .List<Parent>();

I can't for the life of me find the answer anywhere. My brain is not fully functioning today and Google has so far failed me.

+3  A: 

How about something like this?

Session.CreateCriteria<Parent>()
   .CreateCriteria("Children")
   .Add(Expression.Eq("Id", child.Id)
   .List<Parent>();

or

Session.CreateCriteria<Parent>()
   .CreateCriteria("Children")
   .Add(Expression.In("Id", child.Id)
   .List<Parent>();

so you can pass in an array of Ids.

RKitson
Ya, I thought of that, but something about comparing IDs in NHibernate seems wrong. I know it's asthetic, so still would like to know if there is another way.
Stefan Moser
Why wrong? The purpose of Id is to uniquely identify your objects in the DB.
RKitson
Well that's just it, the purpose of the ID is to tell *NHibernate* how to uniquely identify my entities so that I can just deal with objects. If Child was a unary relationship from Parent, I would say Expression.Eq("Child", child) and wouldn't say anything about the ID. I know I'm being nitpicky here, I just figured that something existed in the Criteria API for Contains and could be used just like all other entity comparison is done.
Stefan Moser
Yah, good point. Using the Id has always worked fine for me, but I'd probably use the child object instead also.
RKitson