2009-11-11 3 views
0

У меня есть запрос Criteria Query для сайта социальной сети. Объект Person имеет коллекцию друзей (также объектов человека). Запрос захватывает первых друзей N, но я также хочу, чтобы он загружал связанный объект MainProfileImage, а затем последующий связанный объект MediumThumbnail.NHibernate Lambda Extensions - Eager Загрузка комплектов коллекции

я могу сделать это в HQL легко:

select friends from Person person inner join person.Friends friends inner join fetch friends.MainProfileImage image inner join fetch image.MediumThumbnail where person = :person1 order by friends.LatestLogin desc 

Вот мои критерии усилий. По какой-то причине это ничего не возвращает!

public static IList<Person> GetFriends(Person person, int count) 
{ 
    Person personAlias = null; 
    Person friendAlias = null; 

    ICriteria criteria = NHibernateSessionManager.Instance.GetSession() 
     .CreateCriteria(typeof (Person),() => personAlias) 
     .CreateCriteria(() => personAlias.Friends,() => friendAlias, JoinType.LeftOuterJoin) 
     .CreateCriteria(() => friendAlias.MainProfileImage, JoinType.InnerJoin) 
     .CreateCriteria(() => friendAlias.MainProfileImage.MediumThumbnail, JoinType.InnerJoin) 
     .AddOrder(() => personAlias.LatestLogin, Order.Desc) 
     .Add<Person>(p => p.ID == person.ID) 
     .SetMaxResults(count); 
    return criteria.List<Person>(); 
} 
+0

Почему бы вам просто не оставить HQL на месте? –

ответ

3

Я считаю, что порядок ваших утверждений заставляет запрос генерировать нежелательный SQL, который вы получаете (следовательно, никаких результатов). Вот как это должно быть:

public static IList<Person> GetFriends(Person person, int count) 
{ 
    Person personAlias = null; 
    Person friendAlias = null; 

    ICriteria criteria = NHibernateSessionManager.Instance.GetSession() 
     .CreateCriteria(typeof (Person),() => personAlias) 
     .CreateCriteria(() => personAlias.Friends,() => friendAlias, JoinType.LeftOuterJoin) 
     .Add<Person>(p => p.ID == person.ID) 
     .CreateCriteria(() => personAlias.MainProfileImage, JoinType.InnerJoin) 
     .CreateCriteria(() => personAlias.MainProfileImage.MediumThumbnail, JoinType.InnerJoin) 
     .AddOrder(() => personAlias.LatestLogin, Order.Desc) 
     .SetMaxResults(count); 
    return criteria.List<Person>(); 
} 

Далее по вашему описанию не понятно, из которого ассоциация вы хотите получить данные MainProfileImage и MediumThumbnail с. Когда вы используете его в своем заявлении Criteria, вы запрашиваете данные у основного объекта Person, чьи друзья вы получаете, когда используете friendsAlias. Я изменил его, чтобы использовать personAlias вместо этого, поскольку я считаю, что это означает, что вы хотите связать данные.

+0

Это сработало отлично, спасибо! Мне пришлось изменить friendAlias ​​на personAlias ​​- у меня есть проблемы с моей головой, но это сработало! Обновите свой ответ, чтобы отразить это. Еще раз спасибо! – reach4thelasers

+0

Отвечено обновлено! Чтобы разгадать путаницу с псевдонимами, попробуйте сформулировать запрос. То, что мы говорим в запросе «Критерии», это «получить мне все личные объекты, которые являются друзьями с данным лицом, чей идентификатор у меня есть», что означает, что вы начинаете свой запрос с элементов в коллекции друзей данного человека. Вот почему personAlias ​​относится к вашим результатам (друзьям данного объекта оерсона) и друзьям Aliasas к данному объекту. Путаница также возникает из-за неудачного наименования псевдонимов. – tolism7