Проблема в том, что контакты лениво загружены, т.е.коллекция не извлекается из базы данных в начальном запросе.Я предполагаю, что вы передаете объекты непосредственно в представление, а не с помощью модели представления?У вас есть несколько вариантов, каждый из которых имеет свои недостатки.
Держите сеанс открытым во время обработки представления (так называемый подход Open Session In View).Вы, вероятно, закрываете сеанс NH в контроллере в данный момент, верно?
Стремитесь загрузить весь граф объектов, используя .Not.Lazyload () на контактах.( Не рекомендуется )
Скопируйте все необходимые данные в модель представления в контроллере и передайте их в представление.Используйте Autopper, чтобы помочь вам в этом.
Обновление в ответ на комментарий:
Есть еще большое преимущество в том, что коллекции остаются загруженными.Конечно, в этом контексте вам не выгодно использовать лениво загруженные контакты на объекте клиента, потому что вам нужно их использовать.Но в другом контексте вам могут понадобиться только имя клиента и идентификатор - и вы можете быть уверены, что это не приведет к генерации большого запроса с объединениями и т. Д.
Чтобы использовать Open Session in View, вам не нужно передавать вашоткройте сеанс для представления, скорее вы просто передадите объект, как и раньше, но оставите сеанс открытым - NH автоматически сгенерирует новый запрос, когда вы попытаетесь получить доступ к коллекции контактов.(Это работает, потому что объект клиента все еще «прикреплен» к открытому сеансу за кулисами).Единственная разница здесь в том, что вам нужно закрыть сеанс не в контроллере (где он в настоящее время закрывается явно с помощью .close () или неявно с помощью «using»).Относительно того, где открывать и закрывать сеанс - существуют разные подходы:
В global.asax - открыть в Application_BeginRequest и закрыть в Application_EndRequest (см .: в этой статье ) Я бы порекомендовал начать с этого для простоты, если вы хотите сделать Open Session in View.
В модуле http (в основном то же, что и в предыдущем, но модульном)(см. эту статью )
С этими двумя последними вы, вероятно, подумаете: «Но это будет означать создание сеанса для каждого запроса страницы!»- и вы были бы правы, но неужели сколько страниц не пойдет в БД?Кроме того, создание сеанса облегчается после создания фабрики сеансов.
- Использование атрибута, украшающего метод действия (в основном вы делаете то же самое, что и два последних, но таким образом вы можете выбрать, какойдействия открывают сессию NH).Закройте сеанс в OnActionExecuted, если хотите, чтобы он был закрыт после завершения действия.Закройте в OnResultExecuted, если вы хотите открыть сеанс в представлении.
Конечно, многим людям не нравится Open Session in View, потому что вы не можете контролировать, какие запросы генерируются исключительно в контроллере - представлениевызывает много запросов, это может привести к непредсказуемой производительности.
3 незначительно отличается от 2, потому что в ситуациях, когда вам не нужна отложенная загруженная коллекция, она не извлекается из БД.Например, в этом случае вы можете копировать в ViewModel с полным графом объектов, но в другой ситуации вы можете использовать ViewModel только с именем и идентификатором клиента - в этом случае соединения для коллекции контактов не будут выполняться без необходимости.,По моему мнению, 3 - правильный способ сделать что-то, но в итоге вы создаете гораздо больше объектов (из-за объектов представления).