2013-05-15 2 views
0

도메인 모델에 컬렉션이 포함되어 있고 열심히 가져올 때 종종 동료의 단어 "Cartesian Product"가 들립니다. 제가 아래 모델을 가지고 있다고 가정 해 봅시다.정확히 NHibernate의 데카르트 제품은 무엇입니까?

public class Order{ 
    List<Product> Products 
} 
public class Product{ 
    List<Units> Units 
} 

지금 그들은 내가 제품 및 단위로 주문을 가져 열망을하려고하면, 나는 데카르트 제품 도착하기로되어있어, 말 (중복 일명를 ..). 하지만 ShowSql을 사용하여 테스트 할 때 중복 된 것으로 보이지 않습니다. 이 내 저장소 클래스

public List<Order> GetOrdersWithProductsAndUnits() 
    { 
     return GetSession().Query<Order>() 
          .FetchMany(order => order.Products) 
          .ThenFetch(product => product.Units) 
          .ToList(); 
    } 

입니다 그리고 여기 ShowSql 수 있도록에서 SQL 출력입니다. 이것은 필요한 테이블에 대한 조인으로 예상대로 잘 보입니다.

select order0_.Id as Id8_0_, 
childstock1_.Id as Id23_1_, 
childstock2_.Id as Id24_2_, 
order0_.CustomerName as Customer2_8_0_, 
order0_.City as City8_0_, 
childstock1_.Size as Size23_1_, 
childstock2_.Box as Box24_2_, 
from Orders order0_ 
left outer join Products childstock1_ on order0_.Id=childstock1_.OrderId 
left outer join Units childstock2_ on childstock1_.Id=childstock2_.ProductId 

나는 내 데이터베이스에 125 개 주문을했고 내가 열망 제품 및 단위로 주문을 가져올 때 나는 아직도 (125 개) 기록을 얻을.

List<Order> orders = repository.GetOrdersWithProductsAndUnits(); 
    Assert.That(orders.Count,Is.EqualTo(125)); 

Visual Studio 디버거를 통해 확인하면 제품 또는 단위 수준의 주문 모음에서 중복 된 항목을 찾을 수 없습니다.

카티 전 곱이 중복되어 데이터베이스 (1000에 가까움)에 많은 수의 주문이있을 것으로 예상했습니다. 사소한 것을 놓친 건가요? 데카르트 제품에 대한 제 이해가 왜곡되어 있습니까? 또는 사용하고있는 Query API가 Cartesian Products 문제를 자동으로 해결합니다.

참고 : 데이터 설정도 확실합니다. 나는 Visual Studio Debugger를 통해 디버깅을했고 두 개 이상의 제품과 제품이있는 주문을 확인합니다.

모든 도움말/참조 자료는 높이 평가됩니다.

덕분에 다른 쿼리 유형과는 대조적으로

+0

데이터가 올바르게 설정되어 있습니까? 주문과 관련된 제품이 있습니까? –

+0

예, 확신합니다. Visual Studio 디버그 창을 통해 디버깅했습니다. 각 주문에는 많은 제품이 있고 각 제품에는 많은 단위가 있습니다. –

+0

Ok - 다른 점은 NHibernate가 "추가"레코드를 조정한다는 것입니다. SQL을 직접 실행하고 결과를 보았습니까? 또한, 나는 이것을 * 데카르트 제품으로 만들 수 있다고 생각하지 않습니다. 기술적으로는 모든 제품에 대한 모든 주문을 모든 제품에 적용 할 수 있습니다. 나는 이것이 교차 결합 없이는 가능하지 않다고 생각하지만 잘못 될 수 있습니다. –

답변

0

(HQL은, 기준, QueryOver) NHibernate에 자동으로 LINQ 쿼리에서 중복 루트 개체를 삭제합니다. 그러나 마지막 코멘트에서 말했듯이 여전히 데이터베이스에서 많은 행을 가져 오므로 쿼리가 느려질 수 있습니다.

+0

네가 맞아. NHibernate의 LINQ API가 결과 세트에서 DistinctRootEntityResultTransformer를 자동으로 수행한다는 것이 밝혀졌습니다. 금후..나는 유일한 주문 ID를 얻고 있었지만 주문서에서 중복 된 제품을 발견했습니다 (단위만큼 많은 제품). –

0

HibernatingRhinos와 같은 것을 사용하면 엄청나게 도움이됩니다. 나는 그들의 EF 도구를 사용했고 다른 방법으로는 발생하지 않는다고 생각했던 데카르트 제품에 대한 많은 문제를 피했습니다. Cartesian 제품을 생성하는 ORM의 주요 원인은 일반적으로 객체 트리의로드/딥 읽기입니다. 코드에서 개체를 함께 연결하여 결과 집합을 작성하는 대신보기를 기반으로하는 모델 개체를 사용하면 쉽게 피할 수 있습니다.