我对NHibernate中Flush
(和NHibernate.ISession
)的工作原理感到困惑。
从我的代码中可以看出,当我使用ISession.Save(entity)
保存对象时,该对象可以直接保存到数据库中。
但是,当我使用ISession.SaveOrUpdate(entity)
或ISession.Update(entity)
更新和对象时,数据库中的对象未更新 - 我需要调用ISession.Flush
才能更新它。 / p>
关于如何更新对象的过程如下:
ISession.Get(typeof(T), id)
myCar.Color="Green"
ISession.Update(myCar)
myCar
未更新为数据库。但是,如果我之后调用ISession.Flush
,则会更新。
何时使用Flush
,何时不使用?
答案 0 :(得分: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();
}
实体在提交时更新。 NHibernate看到您的会话是脏的并刷新对数据库的更改。只有在会话之外进行了更改时,才需要更新和保存。 (这意味着使用分离的实体,即会话不知道的实体)。
性能说明: Flush不仅执行必需的SQL语句来更新数据库。它还会搜索内存中的更改。由于POCO上没有脏标志,因此需要将会话中每个对象的每个属性与其第一级缓存进行比较。如果经常这样做,这可能会成为性能问题。您可以采取一些措施来避免性能问题:
答案 1 :(得分:6)
NHibernate只在必要时执行SQL语句。它将尽可能推迟SQL语句的执行。
例如,当您保存具有指定ID的实体时,它可能会推迟INSERT语句的执行。 但是,当您插入一个具有自动增量id的实体时,NHibernate需要直接插入实体,因为它必须知道将分配给该实体的ID。
当您显式调用flush时,NHibernate将执行在该会话中已更改/创建/删除的对象所必需的SQL语句。