3

我有一个使用 nhibernate 和 sqlite DB 用 c# 编写的应用程序。对于单元测试,我使用 xunit 和内存中的 sqlite db。

我知道当会话关闭时内存数据库被破坏,因此为了测试,我使用单个会话并在测试期间保持打开状态。在我的大多数测试中,这都很好。

但是,在少数情况下,我需要测试同时使用ISession和的方法IStatelessSession。经过一番研究,我决定采用与此处描述的方法类似的方法。所以IStatelessSession是使用ISession's 连接创建的,如下所示:

statelessSession = factory.OpenStatelessSession(existingSession.Connection);

问题是,一旦更改持久保存到数据库,这似乎会导致某种冲突。如果我与session.SaveOrUpdate(new Entity() {...})then 进行交易,那很好,但如果我再做,statelessSession.Get<Entity>(1)那么它将失败,并显示错误消息“集合与任何会话无关”。

通常,此错误表明会话已关闭,但在这种情况下,两个会话仍处于打开状态且处于活动状态。

如果我这样做session.Get<Entity>(1),它会按预期返回实体。最初,我认为这可能是因为会话和无状态会话在某种程度上不同步,所以我替换session.SaveOrUpdate..statelessSession.Insert(new Entity() {...})重新运行了测试。奇怪的是,这并没有什么不同。常规会话仍然可以正常工作,并且 statelessSession 仍然损坏。

4

1 回答 1

0

最后,我找到了解决整个问题的方法:

最终,我回到了我的原始查询(一个比上面的示例更复杂的查询,它返回多个结果)并在调试时尝试了各种方法,但都没有解决问题。然后我决定删除该查询的“位置”部分,看看它是否有任何不同。奇怪的是,确实如此。它仍然失败,但这次我得到了一个不同的异常:“无法执行查询”,这也有一个内部异常:“可能对会话进行非线程安全访问”。

整个测试在单个线程上运行,我在调试时通过查看线程视图确认了这一点。所以我想我会撞到另一堵砖墙。然而,经过一番谷歌搜索,我发现这篇博文描述了同样的问题和解决方案:只需更新到最新版本的 nhibernate!

我从 3.1.0 更新到 3.3.1(感谢 NUGet,这很容易)重新运行测试并且它工作正常。把 where 子句放回去,测试就通过了。

于 2013-01-03T11:03:40.800 回答