2011-05-10 4 views
0

이미이 질문을 nh 그룹에 게시했지만 아직 답변을 얻지 못했습니다. 그래서 여기에 게시하고 있습니다. 자식 컬렉션을 열망하고 SetMaxresults를 사용하여 페이징으로 올바른 결과를 얻는 데 약간의 문제가 있습니다. 나는 투표 수집 게으른로드했다 초에SetMaxResults 또는 N + 1을 사용하는 DistinctRootEntityTransformer

public class Post 
{ 
       int Id {get; set;} 
       Vote Votes {get; set;} 
} 

public class Vote 
{ 
       int Id {get; set;} 
} 

을 그리고 그것은 N + 1 SELECT 문을 제외하고 잘 작동 :

의 내가 간단한 엔티티 있다고 가정 해 봅시다.

나는 열심히 'Votes'컬렉션을 잘 가져 왔지만 데이터베이스쪽에는 중복이있었습니다 (하나의 Post에 3 개의 Votes가 있으면 결과 SQL 쿼리에서 3 개의 행이 생길 것입니다). 또한 DistinctRootEntityTransformer를 사용했습니다. 물론 SetMaxResults를 제외하고. SetMaxResults가 데이터베이스 측에서 결과를 제한하기 때문에 DistinctRootEntityTransformer를 적용한 후 객체 측에서 예상되는 결과가 더 적습니다.

블로그 게시물, StackOverflow 질문을 보았습니다. Fetch, LeftOuterJoins, Subqueries, detached criteria와 같은 많은 것을 시도했지만 내 문제에 대한 해결책을 찾지 못했습니다. 이 문제는 여기 http://www.interworks.com/blogs/banderton/2009/06/26/nhibernate-eager-loading-collections-rootentityresulttransformer-and-setm에 설명되어 있습니다.

지금은 세 가지 해결책을 보았습니다. setMaxResults로 잘못된 결과 번호를 얻거나, SELECT N + 1을 유지하거나, 지연로드 된 'vote'컬렉션에 일괄 처리 크기를 설정하십시오. 그게 내가 한 일입니다. 최근의 문제는 NHProf가 최적이 아니므로 일괄 처리 된 선택에 대해 '무제한 결과 집합'경고를 생성한다는 것입니다.

아마도 나는 뭔가를 놓치고 있습니다. 제대로 해결할 수있는 해결책이 있습니까? 사전에

감사합니다,

답변

2

내가 게으른 로딩을 유지하고 선택 N + 1 문제를 완화하기 위해 당신의 매핑에 batch size를 추가하려고 할 것입니다.

<bag name="Votes" cascade="all" batch-size="20"> 
.. 
</bag> 

기본적으로 당신이 배치 크기가 설정과 함께, 데이타베이스 99 개 쿼리를 실행할 것 99 개 행을 한 경우는 설정하지 않고 (20)의 AA 요인에 의해 데이터베이스에 발행 된 쿼리의 양을 줄일 수 batch-size (20)로 설정 012를 넘을 것입니다.

절절한 결합은 Cartesian join을 생성하므로 페이징이 올바르지 않습니다. 또한 DistinctRootEntity은 데이터베이스 자체에 실제로 데이터 NOT의 클라이언트 측 필터링 만 제공합니다.

+0

그게 내가 한거야. NHPS가 최적의 솔루션이 아니므로, NHProf는 최적이 아니므로 일괄 처리 된 선택에 대해 '제한없는 결과 집합'알림을 생성합니다. 나는 우리가 모든 것을 가질 수 없다고 생각합니다 :) 당신의 시간과 내 발견의 확인을 위해 어쨌든 +1 :) –

관련 문제