Справка с исключением ActiveRecord “Не удалось лениво инициализировать коллекцию - нет сеанса”

StackOverflow https://stackoverflow.com/questions/381980

  •  23-08-2019
  •  | 
  •  

Вопрос

Я пишу веб-приложение, используя Castle ActiveRecord, и я продолжаю получать это исключение всякий раз, когда пытаюсь получить доступ к лениво загруженному списку связанных объектов.Вот мой код:

        using(new SessionScope())
        {
            foreach (var field in eventObj.RegistrationFields)
            {
                //Do something with the field here...
            }
        }

Свойство RegistrationFields выглядит следующим образом:

    [HasMany(Inverse = true, Lazy = true)]
    public IList<EventRegistrationField> RegistrationFields { get; set; }

Исключение возникает при обращении к "eventObj.RegistrationFields" для цикла foreach.Я также позаботился о том, чтобы установить атрибут isweb = "true" в настройках моей конфигурации ActiveRecord.Кто-нибудь знает, почему это могло произойти?Вот мой конфиг:

<connectionStrings>
  <add name="main" connectionString="Data Source=localhost\SQLEXPRESS;Initial Catalog=EventScheduler;Integrated Security=SSPI"/>
</connectionStrings>
<activerecord isWeb="true">
  <config>
    <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver"/>
    <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect"/>
    <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider"/>
    <add key="hibernate.connection.connection_string_name" value="main"/>
  </config>
</activerecord>
Это было полезно?

Решение

Я думаю, вы путаетесь в сеансах. RegistrationFields является ленивым свойством eventObj.Это сеанс, который загрузился eventObj это было бы ответственно за загрузку RegistrationFields.Вы явно открываете новый сеанс, используя new SessionScope(), который создает новый сеанс , к которому eventObj не связан;следовательно, у него нет сеанса владения, из которого он мог бы получать данные.Даже если исходный сеанс все еще активен, вызывая new SessionScope() вкладывает новый сеанс и скрывает старый там, где его нельзя увидеть до тех пор, пока Dispose() вызывается в текущей области.Объекты не будут автоматически присоединяться к текущему сеансу.Это ожидаемое поведение NHibernate.

Похоже, вы пытаетесь выполнить session-per-unit-of-work , что нормально, но затем загрузка объектов и разрешение отложенных коллекций всех этих объектов должно происходить в рамках этой единицы работы.

Вы могли бы попробовать перейти к session-per-request (см. Castle docs о том, как это сделать) и отказаться от создания sessionScope.Это сохранит ваши объекты в рабочем состоянии на время запроса страницы (это то, насколько любая отложенная коллекция должна работать в веб-приложении).Однако вы должны знать, что в этом сценарии любое изменение, которое вы вносите в постоянный объект, будет записано в базу данных при сбросе сеанса (по сути, вы должны рассматривать изменение состояния постоянного объекта как изменение базовых данных, как если бы они были одной и той же операцией - тогда вы не ошибетесь).

Другие советы

Когда был загружен eventObj?Это тоже должно быть на сеансе.Кроме того, ознакомьтесь с Интеграция ActiveRecord раздел документации:

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top