帮助ActiveRecord异常"无法懒惰地初始化集合 - 没有会话"

skb*_*skb 3 castle-activerecord lazy-loading

我正在使用Castle ActiveRecord编写一个Web应用程序,每当我尝试访问延迟加载的相关对象列表时,我都会收到此异常.这是我的代码:

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

RegistrationFields属性如下所示:

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

当"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>
Run Code Online (Sandbox Code Playgroud)

Nei*_*itt 6

我觉得你对会话感到困惑.RegistrationFields是一个懒惰的财产eventObj.加载的会话eventObj将负责加载RegistrationFields.您通过使用显式打开新会话new SessionScope(),这会创建一个eventObj未绑定的新会话; 因此没有拥有会话来获取数据.即使始发会话仍然存在,调用new SessionScope()嵌套新会话并隐藏旧会话,直到Dispose()在当前作用域上调用它.对象不会自动附加到当前会话.这是预期的NHibernate行为.

看起来你正在尝试按工作单元进行会话,这很好,但是对象的加载所有这些对象的惰性集合的解析必须在该工作单元内完成.

您可以尝试移动到每个请求的会话(请参阅Castle文档以了解如何实现此目的)并删除SessionScope创建.这将使您的对象在页面请求期间保持活动状态(就任何懒惰的集合应该存在于Web应用程序中).但是,您必须意识到,在这种情况下,您对持久对象所做的任何更改都将在会话刷新时写入数据库(实际上,您应该将对持久对象状态的更改视为对基础更改的更改数据就好像它们是相同的操作 - 然后你就不会出错).