Nhibernate 在本例中,为什么需要session.Clear()来反映数据库中的更改?

Nhibernate 在本例中,为什么需要session.Clear()来反映数据库中的更改?,nhibernate,session,Nhibernate,Session,我有以下代码: public class A { private ISessionFactory _sf; A(ISessionFactory sf) { _sf = sf; } public void SomeFunc() { using (var session = _sf.OpenSession()) using (var transaction = session.BeginTransact

我有以下代码:

public class A
{
    private ISessionFactory _sf;
    A(ISessionFactory sf)
    {
        _sf = sf;
    }

    public void SomeFunc()
    {
        using (var session = _sf.OpenSession())
        using (var transaction = session.BeginTransaction())
        {
            // query for a object
            // change its properties
            // save the object

            transaction.commit();
        }
    }
}
它在单元测试中的用法如下

_session.CreateCriteria ... // some setting up values for this test

var objectA = new A(_sessionFactory);
objectA.SomeFunc();

// _session.Clear();

var someVal = _session.CreateCriteria ... // retrieve value from db to 
                                   //check if it was set to the 
                                   //proper value
                                   //it uses a restriction on a property
                                   //and a uniqueresult to get the object.
                                   //it doesnt use get or load.

Assert.That(someVal, Is.EqualTo(someOtherValue)); // this is false as long 
                                   //as the _session.Clear() is commented. 
                                   //If uncommented, the test passes
我正在对sqlite文件数据库进行测试。在我的测试中,我对数据库做了一些更改,以正确设置它。然后调用SomeFunc()。它进行必要的修改。一旦我回到测试中,会话就不会得到更新的值。它仍然返回调用SomeFunc()之前的值。我必须执行_session.Clear()以使更改反映在测试中的断言中

为什么需要这样做

编辑:cache.use\u二级\u缓存和cache.use\u查询\u缓存均设置为false

Edit2:请在中阅读以下语句

会议将不时举行 执行所需的SQL语句 同步ADO.NET连接的 保持对象状态的状态 在记忆中。这个过程,flush,发生了 默认情况下,在以下几点

* from some invocations of Find() or Enumerable()
* from NHibernate.ITransaction.Commit()
* from ISession.Flush()
上面写着

确保您理解 刷新()。刷新使数据同步 在内存中使用的持久存储 改变,但不是相反

那么,如何更新内存中的对象呢?我知道每个会话都会缓存对象。但是执行UniqueResult()或List()应该与数据库同步并使缓存无效,对吗


我无法理解的是,为什么会话报告陈旧数据?

它取决于您的操作方式。默认情况下,NHibernate具有一级缓存。它使用缓存按ID获取实体,等等

这取决于你做什么样的操作。默认情况下,NHibernate具有一级缓存。它使用缓存按ID获取实体,等等

对象的内存视图(1级缓存)是每个会话的

A接受ISessionFactory并使用其自己的事务作用域打开其自己的会话


即使SomeFunc中使用的ISession的内容被刷新到数据库中,会话也不会看到这些更改,直到其1级缓存被清除。

对象的内存视图(1级缓存)是每个会话的

A接受ISessionFactory并使用其自己的事务作用域打开其自己的会话


即使SomeFunc中使用的ISession的内容被刷新到数据库中,会话也不会看到这些更改,直到其1级缓存被清除。

您有两个会话。一个在A.SomeFunc中,另一个在单元测试中。每个会话在会话缓存(一级缓存)中都有自己的实体实例。这些会话不相互通信或协调。当一个会话写入其更改时,不会通知另一个会话。它的会话缓存中仍然有自己的过时实例


调用_session.Clear()时,通过清除会话缓存使会话“忘记”所有内容。重新查询时,您正在从数据库读取新数据,其中包括来自另一个会话的更改。

您有两个会话。一个在A.SomeFunc中,另一个在单元测试中。每个会话在会话缓存(一级缓存)中都有自己的实体实例。这些会话不相互通信或协调。当一个会话写入其更改时,不会通知另一个会话。它的会话缓存中仍然有自己的过时实例


调用_session.Clear()时,通过清除会话缓存使会话“忘记”所有内容。当您重新查询时,您正在从数据库中读取新数据,其中包括来自其他会话的更改。

您应该编写“做一些工作”部分。您应该编写“做一些工作”部分。我理解您的意思,但文档中的陈述相互冲突。一方面,它说会话永远不会返回过时的数据。另一方面,它说刷新是一个单向过程:内存中的更改进入数据库。那么,会话何时返回正确的数据呢?我必须在查询之前不断清除缓存吗?在这种情况下,缓存有什么意义?我确信我在这里遗漏了一些更好的方面……据我所知,在某些情况下,会话将返回过时的数据,例如在另一个会话中更改数据库,以及在另一个进程更改数据库时。只有当数据库无法从一级(或二级)缓存加载时,NHibernate才会查询数据库。如果需要观察自首次加载数据以来所做的更改,可以调用ISession.execute(对象)从缓存中清除实例,调用ISession.Clear()完全清空缓存,或者调用ISession.Refresh(对象)将内存中的实例更新为当前数据库状态。我明白您的意思,但文件中的陈述相互矛盾。一方面,它说会话永远不会返回过时的数据。另一方面,它说刷新是一个单向过程:内存中的更改进入数据库。那么,会话何时返回正确的数据呢?我必须在查询之前不断清除缓存吗?在这种情况下,缓存有什么意义?我确信我在这里遗漏了一些更好的方面……据我所知,在某些情况下,会话将返回过时的数据,例如在另一个会话中更改数据库,以及在另一个进程更改数据库时。只有当数据库无法从一级(或二级)缓存加载时,NHibernate才会查询数据库。如果需要观察自首次加载数据以来所做的更改,可以调用ISession.execute(对象)从缓存中清除实例,调用ISession.Clear()完全清空缓存,或者调用ISession.Refresh(对象)将内存中实例更新为当前数据库状态。