Управление сессиями NHibernate и отложенная загрузка - PullRequest
17 голосов
/ 23 июня 2009

У меня чертовски много времени пытается выяснить мои проблемы с управлением сессиями в NHibernate. Я предполагаю, что большая часть моих проблем связана с недостатком знаний о понятиях IoC и AOP; по крайней мере, именно об этом я думаю, когда Фабио Мауло продолжает направлять меня.

В любом случае, моя проблема заключается в том, что у меня есть приложение win form, которое выполняет вызовы get и привязывает результат к сетке. После привязки пользователь может выполнить какое-то действие «записи», и это приводит к закрытию сеанса после записи в попытке использовать концепцию сеанса для каждого использования. Затем пользователь может прокручивать сетку, которая вызывает отложенную загрузку, и теперь сеанс закрыт, и я получаю исключение.

Я не хочу, чтобы мой взгляд был осведомлен о моих сессиях, я не хочу отправлять KillAllSessions, когда пользователь закрывает форму. Кроме того, пользователь может иметь несколько открытых форм в любой момент времени, что усугубляет проблемы, связанные с этим методом. По сути, я хочу, чтобы все это работало "за кадром".

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

Мой вопрос, по сути, прежде всего, является ли это правильным способом? Во-вторых, если это так, я даже не знаю, с чего начать. Я никогда не перехватывал вызовы методов, я знал об этом в теории, но не на практике. Я знаю, что есть библиотеки, которые делают подобные вещи, такие как Rhino Commons, но я хочу воспользоваться этой возможностью, чтобы учиться и стать лучшим программистом. Я пытаюсь понять AOP и объекты, связанные с контекстом, но в настоящее время я не пытаюсь понять это. Не могли бы вы, ребята, помочь парню?

Ответы [ 2 ]

7 голосов
/ 24 июня 2009

Я могу придумать несколько вариантов:

Вариант 1. Держите исходный сеанс ISession открытым, пока пользователь взаимодействует с данными, и фиксируйте все изменения сразу после завершения работы пользователя. Это означает, что у вас может быть большое количество незафиксированных изменений в памяти, и другие пользователи не будут видеть ожидающие изменения.

Вариант 2: разделить операции на две единицы работы (UOW). UOW1 только читает и отвечает за заполнение списка. ISession, связанный с UOW1, остается активным, чтобы обеспечить отложенную загрузку, например, в сценарии детализации. UOW2 - это новая недолгая ISession, созданная для редактирования пользователем. Когда редактирование фиксируется, исходный объект выселяется из UOW1, и UOW1 получает новую копию из базы данных.

Вариант 3: воссоздать список после каждого изменения. Это самое простое решение и может подойти для небольших наборов данных.

2 голосов
/ 25 июня 2009

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

Всякий раз, когда я пишу в базу данных, я использую транзакцию begin / commit, которая не закрывает основной сеанс. Соединение с базой данных открывается только NHibernate во время транзакции.

Есть ли причина, по которой вам нужно закрыть сеанс, пока пользователь активно использует форму?

Можете ли вы предоставить более подробную информацию о том, что вы используете для управления сеансом, шаблоном хранилища и т. Д.?

...