2011-10-03 6 views
0

집계 루트가 WallPost입니다. WallPost는 0에서부터 많은 WallPostComments를 가질 수 있습니다.각 엔티티에 대해 모든 하위 항목과 상위 상위 항목 20 개를 가져 오는 방법

20 개의 벽 포스트 (DateCreated 내림차순)를 가져 오는 쿼리를 작성하고 20 개의 벽 포스트에 대한 모든 코멘트를 열심히 가져오고 싶습니다.

나는 Hibernate Linq와 Fetch() 절을 사용하려했지만 "firstResult/maxResults는 콜렉션 가져 오기와 함께 지정되고 메모리에 적용!" 오류. 내가 해봤

다른 두 가지 방법은 다음과 같습니다

var wallPostQuery = _session.QueryOver<WallPost>() 
      .Where(x => x.WallId == wallId) 
      .OrderBy(x => x.DateCreated) 
      .Desc 
      .Left.JoinQueryOver(x => x.Comments) 
      .Take(20) 
      .Future<WallPost>(); 

그러나이 놀라운 놀라운 (물론, 정말)이 다시 0 또는 1 코멘트 각각 스무 벽 게시물을 제공합니다. 내가 원하는 벽이 아닌 중복 된 벽 게시물을 얻습니다.

더 나은 쿼리는

var wallPostQuery = _session.QueryOver<WallPost>().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc.Take(20).Future<WallPost>(); 

_session.QueryOver<WallPost>().Where(x => x.WallId == wallId).Left.JoinQueryOver(x => x.Comments).Future<WallPost>(); 

var wallPosts = wallPostQuery.ToList(); 

이 나에게 관련 코멘트 (20 개) 벽 게시물을 제공하지만, 쿼리가 두 번째 선택이 효율적으로 다시 모든 벽 당기 WallPostComment에 WallPost를 조인이 개 선택으로 실행 게시물 및 댓글 (WallPostId 만 필터링 됨). 작은 수의 게시물이 있지만 잘 작동하지만이 크기 조정을 잘 상상할 수는 없습니다.

더 좋은 방법이 있어야합니다. 그러나 나는 그것을 알아낼 수 없습니다. 어떤 제안?

답변

1

나는 비슷한 (좀 더 복잡한) 문제를 발견 한 solution이 도움이 될 것이라고 생각합니다. 의 라인을 따라
뭔가 : 아마도

var wallPostIdsQuery = _session.QueryOver<WallPost>().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc.Take(20).Future<WallPost>() 
.Select(p => p.Id); 

var wallPostsQuery = _session.QueryOver<WallPost>().WithSubquery.WhereProperty(p => p.Id).In(wallPostIdsQuery); 

var commentsQuery = _session.QueryOver<WallPostComment>().WithSubquery.WhereProperty(p => p.WallPostId).In(wallPostIdsQuery); 

if (wallPostsQuery.Count() == 0) 
{ 
    return wallPostsQuery.List(); 
} 

NHibernateUtil.Initialize(wallPostsQuery.First().Comments); 

이나, 기억하기

var wallPostQuery = _session.QueryOver<WallPost>().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc.Take(20).Future<WallPost>(); 
NHibernateUtil.Initialize(wallPostQuery.First().Comments); 

중요한 것은 단지 두 라인 - 전략을 가져오고 '부속'로 의견 수집을지도하는 것입니다.

+0

도움 주셔서 감사합니다. NHibernate Profiler가 SELECT N + 1 (NHibernateUtil.Initialize가 10 개의 후속 항목을 선택하기 때문에)에 대해 불평하지만, 이것은 내 자신의 솔루션보다 더 행복하다. 이제 - 주석을 가져 오기 위해 생성 된 SELECT 문이 한 번에 두 개의 게시물 (WHERE comments0_.WallPost_id in (193, 192))을 가져옵니다. 한 번에 모두 가져올 수있는 방법이 있습니까? –

+0

이것은 매우 이상하게 보입니다. subselect 전략으로 매핑 된 주석 모음입니까? –

+0

흠 ... 아니, 내가 가진 건 다. var wallPostQuery = _session.QueryOver () .Where (x => x.WallId == wallId) .OrderBy (x => x.DateCreated) .Desc. Take (20) .Future (); NHibernateUtil.Initialize (wallPostQuery.First(). Comments); –

관련 문제