2009-09-01 10 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 содержит 4 единицы, из которых 2 являются дубликатами. Кажется, DistinctRootEntityResultTransformer работает только с коллекциями на 1 уровне, поэтому коллекция родителей дублируется в зависимости от того, сколько дочерних объектов у каждого родителя.

Возможно ли, чтобы NH включал только отдельные родительские объекты?

Большое спасибо.

+0

Вы смогли это решить? Это очень раздражает. –

+0

Да - см. Мой комментарий ниже об изменении IList для ICollection и использовании 'set' в сопоставлениях. – Simon

ответ

1

Если ваше сопоставление установлено в FetchType.Join, попробуйте изменить его на FetchType.Select.

+0

Спасибо mxmissile, тогда он будет работать, хотя вы не можете указать тип выборки в Linq-to-NH (если только я что-то не хватает), и это не то, что я хочу использовать все время, поэтому я неохотно изменяю отображения. Другим решением является изменение коллекции IList <> на ICollection <> и использование 'set' вместо 'bag' в сопоставлении. Я также взломал ResultTransformer вместе, чтобы справиться с этим, и предоставит ссылку здесь, как только у меня получится разумный стандарт. – Simon

+0

@Simon, вы можете указать тип выборки по умолчанию в сопоставлениях – zvolkov

Смежные вопросы