Как управлять сеансами NHibernate в долговременном приложении форм Windows?

Мы используем NHibernate для управления нашей персистентностью в сложном модульном приложении форм Windows, но одна мысль продолжает беспокоить меня. В настоящий момент мы открываем сеанс по запуску и открываем все объекты через этот сеанс. Меня беспокоит, что все загруженные объекты загружаются в кеш сеанса NHibernate, поэтому они не могут быть собраны в мусор, и в конечном итоге мы получим всю базу данных в памяти.

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

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

Что читатели StackOverflow делают, чтобы сохранить преимущества NHibernate без проблем, которые я описываю?

Ответ 1

Айенде и компания обычно рекомендуют использовать сеанс за "разговор". Обычно это приводит к длительности сеанса для очень коротких операций, поэтому он больше похож на веб-приложение.

В случае с деревом вы можете использовать решение № 2 для Bruno просто отлично. Объекты могут быть ленивыми. Затем каждый раз, когда вам нужно получить доступ к дочерней коллекции, вы начинаете разговор и повторно подключаете родителя через ISession.Lock. Затем, когда привязка данных завершена, закройте эту сессию. Не слишком много накладных расходов для поддержания, всего несколько строк кода в любой форме, которая должна вести беседу; вы можете расширить форму и элементы управления, которые вы используете, чтобы сделать это автоматически, если вы чувствуете себя нахальным.

Таким образом, сложная часть - это одновременные изменения из разных сеансов. Пусть не туда!

Ответ 2

Я открываю сеанс, когда мне это нужно, и я закрою его, когда узнаю, что мне больше не понадобится.

Более конкретно, например, если у меня есть форма, которая позволяет мне редактировать информацию о клиенте, например, я открою сеанс, когда форма будет создана, и я закрою сеанс, когда форма закрыта. Когда у меня есть 2 экземпляра этой формы, я также открываю 2 сеанса.

Ответ 3

Я вижу пару альтернатив:

  • Загружать дерево объектов (что из того, что я могу получить из документация, по умолчанию)
  • Отсоедините объекты, перехватите событие "click" и загрузите данные из базы данных, а затем с новым сеансом. Это заставляет вас заботиться о коллекциях самостоятельно, вместо того, чтобы полагаться на nhibernate, что может выходить за рамки вопроса (в котором говорится о преимуществах NHibernate, одним из которых является управление коллекциями).

Ответ 4

Вы можете взглянуть на мои сообщения о том, как использовать uNHAddins для работы с сеансом для разговора в приложении Windows Forms (uNHAddins - это проект с некоторыми дополнениями к NHibernate во главе с Фабио Моло, текущим NH Lead)

Первое сообщение - это

http://gustavoringel.blogspot.com/2009/02/unhaddins-persistence-conversation-part.html

Оттуда у вас есть ссылки на uNHAddins trunk.