относительно первый вопрос. Если вы просто собираетесь читать сущность, вам не нужно ничего делать. Даже присвоение его в качестве поля для другого объекта не потребует блокировки записи. Единственная причина, по которой вам нужно позвонить ISession.Lock
, - это когда вы хотите мутировать, а затем сохранять объект.
Существует исключение и это ленивая загрузка. Если у объекта есть чужие дочерние записи, которые не были загружены, когда первый сеанс был активным, при попытке получить к ним доступ будет вызываться исключение. Самый простой способ обойти это - это прикоснуться к дочерним коллекциям в первом сеансе.
Если сущность по-прежнему создает проблемы в этих условиях, вы можете добавить Load
в свой репозиторий. Вы можете подключить его к ISession.Load
. То, что Load
делает, создает пустой прокси для объекта без попадания в базу данных. Этот объект является частью сеанса, на который загружен объект, и может использоваться для назначения свойствам других объектов. Преимущество такого подхода состоит в том, что он намного чище, и его легко издеваться над модульным тестированием.
относительно второй вопрос. Да, вы правы, что пахнет интеграцией ISession.Lock
в репозиторий. Опять же, когда вам не нужно мутировать сущность, вам не нужно беспокоиться об этом. Но, когда вы, ну, вы действительно должны думать о простое повторное загрузку объекта из репозитория и работу над ним. Я знаю, что это не так оптимально, как может быть, но это экономит вам очень странный код, особенно в ваших модульных тестах.
Последнее изделие. Я понимаю, что вы говорите об объекте, который будет жить в течение длительного времени (возможно, полной продолжительности работы приложения). У вас есть примерно три категории жизни: 1. навсегда, 2. длинные и 3. короткие. Причина, по которой я упоминаю об этом, заключается в том, что не один раз проблемы с сущностями, которые имеют «длительный» жизненный цикл, действительно могут оставаться подключенными к сеансу, который имеет одинаковое время жизни. Нет проблем, если сеанс будет активным, скажем, 5 или 10 минут (время ввода данных пользователем в форму). Это само по себе сэкономит большинству людей много неприятностей.
Еще одно примечание: посмотрите на NHibernateUtil
и NHibernateProxyHelper
. Эти классы могут помочь вам принудительно загрузить объекты и дочерние коллекции.
Почему вы сохраняете объекты в памяти после закрытия сессии? Мне никогда не приходилось это делать. – Paco
@Paco: Я создаю много новых объектов, которые ссылаются на существующие, уже сохранившиеся объекты. – Groo
Я имею в виду, почему вы храните их в памяти вместо того, чтобы извлекать их из базы данных? Разве это не приведет к повреждению базы данных при сбое транзакции? – Paco