2012-06-01 2 views
0

다음 데이터베이스 구조를 가지고 있습니다. 보고서를 위해 전체적으로 트래버스해야합니다.NHibernate를 사용하여 별도의 SELECT로 여러 개의 중첩 컬렉션을 열심히 가져 오는 것

Product -> ProductVariation -> ProductMedaItem 
Product -> CategoryLinks -> Category 

은 내가 Products 테이블에 쿼리를 가지고, 내가 함께 그들 모두를 액세스하는 바와 같이, 위의 데이터를 프리 페치합니다. 조합이 폭발하여 많은 양의 데이터가 생성되므로 JOIN을 사용하지 않는 것이 좋습니다.

내 눈에 이상적인 솔루션이 될 것입니다 다음

쿼리가 발행
  • 그런 다음, 결과 세트가 구문 분석됩니다 일치하는 모든 제품을로드하고, 모든 제품의 변형을 기반으로, 함께로드됩니다 'Select * from ProductVariations where ProductId in ([all_product_id_set])'과 유사한 쿼리에서
  • 다시이 결과 집합을 파싱 모든 ProductMediaItem 등등 Select * from ProductMediaItem where ProductVariationId in ([all_product_variation_id_set]);
  • 유사한 등

이 각각 다른 연관 하나 SELECT 초래 쿼리를 사용하여 페치된다. 따라서 모든 제품 변형, 미디어 항목 및 각 제품 범주 링크를로드하려면 해당 범주가 5 SELECT이됩니다.

criteria.SetFetchMode("ProductVariations", FetchMode.Select")을 사용해 보았지만 아무런 변화가 없습니다. 현재 해결 방법은 일괄 처리를 사용하는 것입니다.하지만이 방법은 모든 데이터를 얻기 위해 약 50 - 60 개의 쿼리를 생성합니다. 속도는 그렇게 느리지 만 훨씬 빨라질 수 있습니다.

NHibernate - 3.3의 최신 버전을 사용하고 있습니다.

내가 정상 OOP, 예를 사용하여 컬렉션을 통과하고 싶습니다 1

업데이트 :

foreach (var p in Products) 
{ 
    foreach (var variation in p.ProductVariations) 
    { 
     foreach (var mediaItem in variation.MediaItems) 
     { 
       ... 
     } 
    } 
} 

답변

0

MultiQueries 및 MultiCriteria이 작동, 또는 더 쉽게는, 예를 선물 할 것을 :

var productVariations = session.CreateQuery(
     "Select * from ProductVariations where ProductId in ([all_product_id_set])") 
     .Future<ProductVariations>(); 

var mediaItems = session.CreateQuery(
     "select pv.MediaItems from ProductVariations pv where pv.ProductId in ([all_product_id_set])") 
     .Future<ProductMediaItem>(); 

등 ... 이들 중 하나를 열거하면 그것은 1 개의 모든 쿼리를 실행합니다. 유일한 "속임수"는 당신이 선택하고자하는 다양한 아이템으로 Product에서 관계를 아래로 탐색하는 것입니다.

+0

그것은 작동 할 것이지만 NHibernate가 컬렉션을 자동으로 프리 페치하고 싶습니다. , 정상적인 코드 구조를 사용하여. 따라서, 제품 목록을로드 할 것이고,'Products [0] .ProductVariations [0] .ProductMediaItems [0]'라고 말하면 액세스 할 필요는 없지만 이미 있습니다. –