NHibernate Flush——它是如何工作的?

NHibernate Flush——它是如何工作的?,nhibernate,Nhibernate,我对NHibernate中的Flush(和NHibernate.iseSession)是如何工作的感到困惑 从我的代码来看,当我使用ISession.Save(entity)保存对象时,该对象可以直接保存到数据库中 但是,当我使用ISession.SaveOrUpdate(entity)或ISession.update(entity)更新和对象时,数据库中的对象没有更新---我需要调用ISession.Flush来更新它 有关如何更新对象的过程如下所示: 使用ISession.Get(typeo

我对NHibernate中的
Flush
(和
NHibernate.iseSession
)是如何工作的感到困惑

从我的代码来看,当我使用
ISession.Save(entity)
保存对象时,该对象可以直接保存到数据库中

但是,当我使用
ISession.SaveOrUpdate(entity)
ISession.update(entity)
更新和对象时,数据库中的对象没有更新---我需要调用
ISession.Flush
来更新它

有关如何更新对象的过程如下所示:

  • 使用
    ISession.Get(typeof(T),id)
  • 更改对象属性,例如,
    myCar.Color=“Green”
  • 使用
    ISession.Update(myCar)
  • myCar
    未更新到数据库。但是,如果我随后调用
    ISession.Flush
    ,则它会被更新


    何时使用Flush,何时不使用?

    NHibernate仅在必要时执行SQL语句。它将尽可能长时间地推迟SQL语句的执行

    例如,保存具有指定id的实体时,可能会推迟INSERT语句的执行。 但是,例如,当您插入具有自动递增id的实体时,NHibernate需要直接插入该实体,因为它必须知道将分配给该实体的id

    当显式调用flush时,NHibernate将执行该会话中已更改/创建/删除的对象所需的SQL语句


    在许多情况下,您不必在意NHibernate的冲洗时间

    如果您创建了自己的连接,则只需调用flush,因为NHibernate不知道您何时提交它

    对你来说真正重要的是交易。在事务期间,您与其他事务隔离,这意味着您在读取数据库表单时始终可以看到您的更改,而不会看到其他更改(除非已提交)。因此,您不必关心NHibernate何时更新数据库中的数据,除非它已提交。无论如何,它对任何人都不可见

    NHibernate在以下情况下刷新

    • 你称之为提交
    • 在查询之前,确保按内存中的实际状态进行筛选
    • 当你叫同花顺的时候
    例如:

    using (session = factory.CreateSession())
    using (session.BeginTransaction())
    {
      var entity = session.Get<Entity>(2);
      entity.Name = "new name";
    
      // there is no update. NHibernate flushes the changes.
    
      session.Transaction.Commit();
      session.Close();
    }
    
    使用(session=factory.CreateSession())
    使用(session.BeginTransaction())
    {
    var entity=session.Get(2);
    entity.Name=“新名称”;
    //没有更新。NHibernate刷新更改。
    Commit();
    session.Close();
    }
    
    实体在提交时更新。NHibernate发现您的会话是脏的,并刷新对数据库的更改。只有在会话之外进行更改时,才需要更新和保存。(这意味着使用分离实体,即会话不知道的实体)


    性能说明:Flush不仅执行更新数据库所需的SQL语句。它还搜索内存中的更改。由于POCOs上没有脏标志,它需要将会话中每个对象的每个属性与其一级缓存进行比较。如果太频繁,这可能会成为性能问题。为了避免性能问题,您可以做以下几件事:

    • 不要在循环中冲洗
    • 避免序列化对象(检查更改时需要序列化)
    • 适当时使用
    • 适当时设置
    • 在属性中使用自定义类型时,请实现高效的Equals方法
    • 当您确信自己知道自己在做什么时,请小心禁用自动刷新

    谢谢,但当我更新数据库中的对象时,这是否意味着我创建了自己的事务?或者为什么我需要调用flush来更新数据库?我必须修复它:当您创建自己的连接时,您需要刷新。如果调用CreateSession,NHibernate会为您创建一个连接,但您可以提供自己的ADO.NET连接。通常你不需要这个。如果不这样做,则不需要调用flush。所提供链接的可能副本不起作用。上面写着“此内容在Knol上不再可用”。@N30:我刚刚修复了链接。