我正在使用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>
答案 0 :(得分:6)
我认为你对会话感到困惑。 RegistrationFields
是eventObj
的懒惰属性。加载eventObj
的会话将负责加载RegistrationFields
。您正在使用new SessionScope()
明确打开一个新会话,这会创建一个未绑定eventObj
的新会话;因此没有拥有会话来获取数据。即使始发会话仍处于活动状态,调用new SessionScope()
也会嵌套新会话并隐藏旧会话,直到在当前作用域上调用Dispose()
之后才能看到它。对象不会自动附加到当前会话。这是预期的NHibernate行为。
看起来你正在尝试按工作单元进行会话,这很好,但是加载对象和所有这些对象的延迟集合的解析必须发生在那个工作单元内。
您可以尝试转移到每个请求的会话(请参阅Castle文档了解如何实现此目的)并删除SessionScope创建。这将使您的对象在页面请求期间保持活动状态(就任何懒惰的集合应该存在于Web应用程序中)。但是,您必须意识到,在这种情况下,您对持久对象所做的任何更改都将在会话刷新时写入数据库(实际上,您应该将对持久对象状态的更改视为对基础更改的更改数据就好像它们是相同的操作 - 那么你就不会出错。)
答案 1 :(得分:1)
eventObj何时加载?这也需要在会议中。另外,请查看文档的ActiveRecord integration部分: