3

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

        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; }

当为 foreach 循环访问“eventObj.RegistrationFields”时会发生异常。我还确保在我的 activeRecord 配置设置中设置了 isweb="true" 属性。有谁知道为什么会发生这种情况?这是我的配置:

<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>
4

2 回答 2

6

我认为您对会话感到困惑。RegistrationFields是 的惰性属性eventObj。加载的会话eventObj将负责加载RegistrationFields。您正在使用 明确打开一个新会话new SessionScope(),这会创建一个eventObj未绑定的新会话;因此它没有拥有会话来获取数据。即使原始会话仍然存在,调用也会嵌套一个新会话并隐藏旧会话,直到在当前范围内调用new SessionScope()它才能看到。Dispose()对象不会自动将自己附加到当前会话。这是预期的 NHibernate 行为。

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

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

于 2008-12-22T12:09:20.223 回答
1

eventObj 是什么时候加载的?这也需要在会话中。此外,请查看文档的ActiveRecord 集成部分:

于 2008-12-19T20:14:49.137 回答