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

Gra*_*ton 20 nhibernate

我对NHibernate中的Flush(和NHibernate.ISession)工作方式感到困惑.

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

然而,当我更新和使用对象ISession.SaveOrUpdate(entity)ISession.Update(entity)在数据库中的对象不更新---我需要调用ISession.Flush,以更新它.

我如何更新对象的过程如下:

  1. 使用从数据库中获取对象 ISession.Get(typeof(T), id)
  2. 例如,更改对象属性 myCar.Color="Green"
  3. 使用将其提交回数据库 ISession.Update(myCar)

myCar不会更新到数据库.但是,如果我ISession.Flush之后打电话,那么它会更新.

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

Ste*_*ger 28

在很多情况下,当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();
}
Run Code Online (Sandbox Code Playgroud)

实体在提交时更新.NHibernate看到您的会话是脏的并刷新对数据库的更改.只有在会话之外进行了更改时,才需要更新和保存.(这意味着使用分离的实体,即会话不知道的实体).


性能注意事项: Flush不仅执行必需的SQL语句来更新数据库.它还会搜索内存中的更改.由于POCO上没有脏标志,因此需要将会话中每个对象的每个属性与其第一级缓存进行比较.如果经常这样做,这可能会成为性能问题.您可以采取一些措施来避免性能问题:

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


Fre*_*els 6

NHibernate只在必要时执行SQL语句.它将尽可能推迟SQL语句的执行.

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

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

红晕