我有一个使用带有sqlite DB的nhibernate用c#编写的应用程序。对于单元测试,我使用的是xunit和内存中的sqlite db。
我知道内存数据库在会话关闭时被破坏,所以为了测试,我使用单个会话并在测试期间保持打开状态。在我的大多数测试中,这都可以。
但是,在少数情况下,我需要测试同时使用ISession
和IStatelessSession
的方法。经过一番研究,我找到了与here描述的方法类似的东西。因此IStatelessSession
是使用ISession
的连接创建的,如下所示:
statelessSession = factory.OpenStatelessSession(existingSession.Connection);
问题是,只要持续更改数据库,这似乎就会引起某种冲突。如果我与session.SaveOrUpdate(new Entity() {...})
进行交易,那就没问题,但如果我再做一个statelessSession.Get<Entity>(1)
,那么它将失败,并显示错误消息“集合与任何会话无关”。
通常,此错误表示会话已关闭,但在这种情况下,两个会话仍处于打开状态且处于活动状态。
如果我session.Get<Entity>(1)
,它会按预期返回实体。最初,我认为这可能是因为会话和无状态会话在某种程度上不同步所以我用session.SaveOrUpdate..
替换statelessSession.Insert(new Entity() {...})
并重新进行测试。奇怪的是,这没有任何区别。常规会话仍然正常,statelessSession仍然被打破。
答案 0 :(得分:0)
最后,我找到了解决这个问题的方法:
最后,我回到原始查询(比上面的示例更复杂的查询返回多个结果)并在通过它进行调试时尝试了各种各样的事情,但没有一个能够解决问题。 然后我决定删除该查询的“where”部分,看它是否有所不同。奇怪的是,确实如此。 它仍然失败,但这次我得到了一个不同的例外:'无法执行查询',这也有一个内部异常:'可能的非线程安全访问会话'。
整个测试在一个线程上运行,我通过在调试时查看线程视图来确认这一点。所以我以为我会碰到另一堵砖墙。然而,经过一些谷歌搜索,我发现this blog post描述了同样的问题和解决方案:只需更新到最新版本的nhibernate!
我从3.1.0更新到3.3.1(感谢NUGet,这是一件轻而易举的事)重新运行测试并且工作正常。将where子句放回去,测试通过。