2013-02-08 3 views
3

У меня есть 2 объекта в моем домене А и ВFluent NHibernate циклическую боль

Объекта А имеет свойство B объекта B имеет свойство списка

, когда я делаю удар по моему дб , из B, он возвращает список As, но каждый A имеет B, который, в свою очередь, имеет список As. снова и снова и снова.

очевидно ленивая проблема с загрузкой. Ленивая загрузка, но моя проблема заключается в том, что это служба WCF, мне нужно, чтобы преобразовать все мои объекты домена в DTO объекты, чтобы отправить вниз провод, и когда я делаю это делает следующее - псевдокод

ADTO adto Transform(ADomain a) 
{ 
    adto.name = a.name; 
    adto.surname = a.surname; 
    adto.B = Transform(a.B); 
} 

BDTO bdto Transform(BDomain b) 
{ 
    bdto.bob = b.bob; 
    foreach (A a in b.As) 
    { 
     bdto.bs.add(Transform(a)); 
    } 
} 

так как я могу сделать выборку коллекции только одним слоем.

отображение Б:

HasMany(x => x.As) 
      .Cascade.AllDeleteOrphan() 
      .Fetch.Select() 
      .Inverse().KeyColumn("AId"); 

отображение A в:

References(x => x.B).Column("AId"); 
+0

возможно дубликат [циркулярное Reference, NHibernate и WCF] (http://stackoverflow.com/questions/1560846/circular-reference-nhibernate-and-wcf) – Peter

ответ

1

Ну, передать циклическую ссылку через WCF, вы должны настроить родительский DTO (B) с IsReference параметром DataContractAttribute.IsReference Property(или здесь The Problem of Circular References).

Используйте свойство IsReference, чтобы инструктировать DataContractSerializer вставить XML-конструкции, которые сохраняют справочную информацию объекта. [DataContract(Namespace = "http://domain.../", IsReference=true)] класс BDTO общественного ...

Чтобы дать вам ответ:

... так как я могу сделать мой забрать из коллекции идти только один слой глубокий.

В NHibernate не будет проблем с циркулярными ссылками. И даже более того, вы можете легко получить все данные, выполняя только 2 SQL-запроса. Настройте отображение:

HasMany(x => x.As) 
    .Cascade.AllDeleteOrphan() 
    .BatchSize(25) 
    //.Not.LazyLoad() 
    .Inverse() 
    .KeyColumn("AId"); 

ПРИМЕЧАНИЕ: Not.LazyLoad имеют смысл только тогда, когда объект почти всегда требуется, чтобы получить B работать. Когда используется «ленивый» режим, вы должны держать сеанс открытым во время обработки всей службы WCF.

Параметр BatchSize оптимизирует списки загрузки объектов B. Читайте больше здесь: http://ayende.com/blog/3943/nhibernate-mapping-set

Сессия NHibernate выполнит два запроса: 1) Select B и 2) Select A for all B и материализует результаты в полные экземпляры A и B, причем ссылки в обоих направлениях полностью заполнены. Сеанс NHibernate будет обслуживать вас полностью загруженные экземпляры. Даже называет Get<A>(id) и Get<B>(id) будет извлекать объекты из сессии

Следующие шаги к вам, вы можете использовать объекты DTO, картографические инструменты для преобразования их ...