帮助解决 ActiveRecord 异常“无法延迟初始化集合 - 无会话”

发布于 2024-07-10 05:41:29 字数 1307 浏览 7 评论 0原文

我正在使用 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>

I am writing a web app using Castle ActiveRecord, and I keep getting this exception whenever I try to access a lazy loaded list of related objects. Here is my code:

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

The RegistrationFields property looks like this:

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

The exception happens when the "eventObj.RegistrationFields" is accessed for the foreach loop. I also made sure to set the isweb="true" attribute in my activeRecord config settings. Does anyone know why this would happen? Here is my config:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

永言不败 2024-07-17 05:41:29

我认为您对会话感到困惑。 RegistrationFieldseventObj 的惰性属性。 加载 eventObj 的会话将负责加载 RegistrationFields。 您使用 new SessionScope() 显式打开一个新会话,这将创建一个未绑定 eventObj 的新会话; 因此没有所属会话可供其获取数据。 即使原始会话仍处于活动状态,调用 new SessionScope() 也会嵌套一个新会话,并将旧会话隐藏在调用 Dispose() 之前无法看到的位置在当前范围内。 对象不会自动将其自身附加到当前会话。 这是 NHibernate 的预期行为。

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

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

I think you're getting confused about sessions. RegistrationFields is a lazy property of eventObj. It is the session that loaded eventObj that would be responsible for loading RegistrationFields. You're explicitly opening a new session by using new SessionScope(), which creates a new session to which eventObj is not bound; therefore there is no owning session for it to get the data from. Even if the originating session is still alive, calling new SessionScope() nests a new session and hides the old one where it can't be seen until Dispose() is called on the current scope. Objects will not automatically attach themselves to the current session. This is the expected NHibernate behaviour.

It looks like you're trying to do session-per-unit-of-work, which is fine, but then the loading of objects and the resolution of all those objects' lazy collections must happen within that unit of work.

You could try moving to session-per-request (see the Castle docs for how to make this happen) and dropping the SessionScope creation. This will keep your objects live for the duration of a page request (which is as far as any lazy collection should live in a Web app). You must be aware, though, that in this scenario any change you make to a persistent object will be written to the DB on session flush (in effect, you should treat a change to the state of a persistent object as a change to the underlying data as if they were the same operation - then you can't go wrong).

冷情妓 2024-07-17 05:41:29

eventObj 何时加载? 这也需要在会议中进行。 另外,请查看文档的 ActiveRecord 集成 部分:

When was eventObj loaded? That needs to be in the session too. Also, check out the ActiveRecord integration section of the docs:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文