2009-09-01 4 views
4

NHibernate 작은 데이터 계층 구조를로드하려고하면 문제가있어. 내 도메인 모델은 다음과 같습니다.NHibernate 자식 및 하위 자식 컬렉션을 로딩 열심히

class GrandParent 
{ 
    int ID{get;set;} 
    IList<Parent> Parents {get; set;} 
} 

class Parent 
{ 
    IList<Child> Children {get; set;} 
} 

class Child 
{ 
} 

및 주어진 GrandParent에 대한 모든 부모와 자녀를 열렬히로드하고 싶습니다. 이 linq-to-NH 쿼리는 올바른 SQL을 생성하고 예상대로 GrandParent를로드합니다. (예에서는 조부모에 각각 2 개의 하위 개체가있는 2 명의 부모가 있으므로 총 4 개의 하위 개체가 있다고 가정합니다.

var linq = session.Linq<GrandParent>(); 
linq.Expand("Parents"); 
linq.Expand("Parents.Children"); 
linq.QueryOptions.RegisterCustomAction(c => 
    c.SetResultTransformer(new DistinctRootEntityResultTransformer())); 
var grandparent = (select g from session.Linq<GrandParent>() 
        where g.ID == 1 
        select g).ToList(); 

Assert(grandparent.Count == 1); //Works 
Assert(grandparent.Parents.Count == 2); //Fails - count = 4! 

grandparent.Parents 컬렉션에는 2 개의 중복 항목이 포함되어 있습니다. DistinctRootEntityResultTransformer는 1 레벨 깊이의 콜렉션에서만 작동하므로, 각 부모가 가진 얼마나 많은 Child 객체에 따라 Parents 콜렉션이 복제됩니다.

NH가 고유 한 부모 개체 만 포함하도록 할 수 있습니까?

대단히 감사합니다.

+0

이 문제를 해결할 수 있었습니까? 정말 짜증나. –

+0

예 - IList for ICollection을 변경하고 매핑에서 'set'을 사용하는 것에 대한 아래 내 의견을 참조하십시오. – Simon

답변

1

매핑이 FetchType.Join으로 설정된 경우 FetchType.Select로 변경해보십시오.

+0

Linq-NH에서 가져 오기 유형을 지정할 수는 없지만 mxmissile 덕분에 작동합니다. (뭔가 빠뜨린 것이 아니라면) 그리고 항상 사용하고 싶은 항목이 아니므로 해당 항목을 수정할 필요가 없습니다. 매핑. 또 다른 해결 방법은 IList <> 컬렉션을 ICollection <>으로 변경하고 매핑에서 'bag'대신 'set'을 사용하는 것입니다. 나는 또한 이것을 처리하기 위해 함께 ResultTransformer를 해킹했고, 일단 합리적인 표준에 도달하면 여기에 링크를 제공 할 것이다. – Simon

+0

@imon, 매핑에서 기본 가져 오기 유형을 지정할 수 있습니다 – zvolkov

관련 문제