2009-10-13 6 views
2

Эта проблема возникает по сети в течение многих лет, я пока не нашел хорошего решения. Тема проходит список объектов, которые имеют циклическую ссылку внутри них населена NHibernate (с или без ленивых нагрузки - некоторые сайты не ВОФК может быть сделано с ленивым)Циркулярная ссылка, NHibernate и WCF

Вот пример:

[DataContract] 
class Person 
{ 
    [DataMemeber] 
    string Name 
    [DateMember] 
    IList<Child> myChilds; 
} 

[DataContract] 
class Child 
{ 
    [DataMemeber] 
    string Name 
    [DateMember] 
    Person Father 
} 

Когда я пытаюсь получить все лица в моей БД: Серверный код будет:

ICriteria crit = session.CreateCriteria(typeof(Person))); 
IList<Base> queryResult = crit.List<Base>(); 

Я получаю хорошие результаты на серверном побочные список всех человека, так и внутри каждого человека, Я получаю Список всех сыновей (и внутри каждого сына - я получаю объект Лица, у которого внутри есть список его сыновей и т. д.)

Теперь, пытаясь получить этот список по WCF, вызывается канал. (если я удалю объект Person из ребенка - он отлично работает).

Решения Я пробовал и не решил эту проблему: Добавление IsReference = true в [DataContract] - не помогло. Перемещение всего отображения на not.Lazyload() - не помогло.

Любые идеи, как решить эту проблему без перезаписи WCF?

Спасибо, Дани

ответ

2

http://www.jameskovacs.com/blog/CommentView.aspx?guid=477b077c-e65e-4547-8289-4e1bc17b3de7

Эта статья решает эту проблему.

EDIT:

Ссылка, по-видимому был мертв в течение некоторого времени. Используйте машину Wayback, чтобы просмотреть ее заархивированную версию здесь: http://web.archive.org/web/20070219214621/http://www.jameskovacs.com/blog/CommentView.aspx?guid=477b077c-e65e-4547-8289-4e1bc17b3de7

+0

Ссылка была нарушена на данный момент. – Restuta

+0

Ссылка по-прежнему отсутствует - 404. – ssmith

0

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

+0

Размер по умолчанию WCF составляет 512K. У меня есть только 5 объектов «Личность», и только у одного из них есть сын. Это может быть проблема размера - из-за бесконечной петли сериализации, но исходная структура - это не более нескольких ... – Dani

0

IsReference действительно является официальным ответом здесь, если вы хотите фактически сохранить форму графа объекта. См. http://msdn.microsoft.com/en-us/library/cc656708.aspx. Можете ли вы рассказать о том, что вы имеете в виду, когда говорите «это не помогло»? Где именно вы положили IsReference? Как на стороне клиента, так и на стороне сервера? Какие ошибки вы наблюдали?

Если вы не заботитесь о сохранении ref, существуют различные решения, которые включают в себя разрыв бесконечного эталонного цикла. Самый простой из них - удалить атрибут DataMember из «Отца». Или что-то с «теневой собственности»:

public Person Father; 
[DataMember] public string FatherName 
{ get {return Father.Name;} set {/* ... */ }} 

Это действительно сильно зависит от ваших конкретных требований ...

+0

Я поместил IsReference в атрибут DataContract, В связанной статье они говорят, что это должно быть на проблемном [DataMember] НО ... удивительно - [DataMember] не знает об этом флаге. этот код не будет компилироваться !! (что очень странно, что источником примера является MSDN ...) Systme.RunTime.Serialization DataMemberAttribute не содержит определения для IsReference = true ..... The Puzzle. – Dani

+0

Хм, да, не заметил, что тема была сломана ... Still: - Вы положили IsReference на типы Child и Person? - Что произошло именно тогда, когда вы попробовали IsReference? (Исключения и т. Д.?) –

+0

То же Исключение - как ничего не изменилось. Исключение - общее, ничего конкретного. Я прочитал статью, предлагающую перейти на другой сериализатор. Я проверяю этот параметр, и я отчитаюсь здесь. Я спросил кого-то @ Microsoft об этой статье, все еще ожидая ответа. – Dani

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