Поиск NHibernate в списке с использованием критериев ICriteria

У меня есть класс X:

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

Мое сопоставление ClassX (с использованием Fluent)

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

Мой класс Y:

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

Отображение ClassY

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

Теперь я хотел бы найти все элементы ClassX, которые есть в ListY Z.ID = 2 ...

Как я могу это сделать с помощью ICriteria?

Спасибо


person Paul    schedule 09.11.2009    source источник


Ответы (3)


С критериями?

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

Имейте в виду, что у вас может быть только один CreateCriteria, вы можете использовать псевдоним для добавления ограничений на другие свойства.

Обновление после вашего комментария:

о, моя ошибка, я думаю, вам нужно использовать HQL:

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

Потому что не уверен, что это сработает:

Session.CreateCriteria<ClassX>()    
       .CreateCriteria("ListY")
       .CreateAlias("Z", "z")
       .Add(Expression.Eq("z.Id", 2)
       .List<ClassX>();
person MatthieuGD    schedule 09.11.2009
comment
Но в моем ListY есть элементы ClassZ внутри ... А те элементы Z должны быть в Expression, верно? - person Paul; 09.11.2009

Я думаю, что это должно сработать:

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>();
person queen3    schedule 09.11.2009

Если мы разбиваем этот поиск по критериям на этапы, это может помочь вам в понимании. Насколько мне известно, здесь есть два решения. Первый вариант - создать объект ICriteria для двух других классов. Это выглядело бы так:

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>();

Второй вариант использования псевдонимов:

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>();
person DigitalNomad    schedule 09.11.2009