views:

159

answers:

3

Hello...

I have my class X :

public class ClassX
{
   public virtual IList<ClassY> ListY { get; set; }
   ...
}

My ClassX mapping (using Fluent)

 ...
 HasMany<ClassX>(x => x.ListY )
        .Inverse()
        .Cascade.AllDeleteOrphan()
        .KeyColumns.Add("`IDX`");
 ...

My Y class:

 public class ClassY
 {
     ...
     public virtual ClassZ Z{ get; set; }
     ...
 }

Mapping ClassY

 ...
 References(x => x.Z, "IDZ").Cascade.None();
 ...

Now, I´d like to search all ClassX elements that have in ListY Z.ID = 2...

How can I do that using ICriteria?

Thanks

+3  A: 

With a criteria ?

Session.CreateCriteria<ClassX>()    
   .CreateCriteria("ListY")
   .Add(Expression.Eq("Id", 2)
   .List<ClassX>();

Be aware that you can have only one CreateCriteria, yu can use alias to add restrictions on other properties.

Update after your comment :

oh my mistake, I think you need maybe to use HQL :

select x fron ClassX as x 
left join x.ListY listY
left join listY.Z z
where z.Id=2

Because I'm not sure that this will work :

Session.CreateCriteria<ClassX>()    
       .CreateCriteria("ListY")
       .CreateAlias("Z", "z")
       .Add(Expression.Eq("z.Id", 2)
       .List<ClassX>();
Matthieu
But my "ListY" has "ClassZ" elements inside... And are those "Z" elements that should be on Expression, right?
Paul
+1  A: 

I think either of this should work:

Session.CreateCriteria<ClassX>()    
       .CreateAlias("ListY", "y")
       .CreateAlias("y.Z", "z")
       .Add(Expression.Eq("z.Id", 2))
       .List<ClassX>();

Session.CreateCriteria<ClassX>()    
       .CreateAlias("ListY", "y")
       .Add(Expression.Eq("y.Z.Id", 2))
       .List<ClassX>();
queen3
+1  A: 

It may help your understanding if we break this criteria search down into steps. To my knowledge there are two solutions here. The first option is to create an ICriteria object for your other two classes. It would look like this:

ICriteria classXCriteria = Session.CreateCriteria<Class>();
ICriteria classYCriteria = classXCriteria.CreateCriteria<classY>();
ICriteria classZCriteria = classYCriteria.CreateCriteria<classZ>();

classZCriteria.Add(Expression.Eq("Z", [id to search on goes here]));

IList<ClassX> results = classXCriteria.List<ClassX>();

The second option to to use aliases:

ICriteria classXCriteria = Session.CreateCriteria<ClassX>();
classXCriteria.CreateAlias("ListY", "classY");
classXCriteria.CreateAlias("classY.Z", "classZ");
classXCriteria.Add(Expression.Eq("classZ.Id", [id to search on goes here]));

IList<ClassX> results = classXCriteria.List<ClassX>();
Greg Bahrey