问题描述
我对NHibernate中的Flush
(和NHibernate.ISession
)如何工作感到困惑.
I am kind of confused on how Flush
( and NHibernate.ISession
) in NHibernate works.
从我的代码看来,当我使用ISession.Save(entity)
保存对象时,该对象可以直接保存到数据库中.
From my code, it seems that when I saved an object by using ISession.Save(entity)
, the object can be saved directly to the database.
但是,当我使用ISession.SaveOrUpdate(entity)
或ISession.Update(entity)
进行更新和对象时,数据库中的对象未更新---我需要调用ISession.Flush
来对其进行更新.
However, when I update and object using ISession.SaveOrUpdate(entity)
or ISession.Update(entity)
, the object in the database is not updated--- I need to call ISession.Flush
in order to update it.
有关如何更新对象的过程如下:
The procedure on how I update the object is as follows:
- 使用
ISession.Get(typeof(T), id)
从数据库中获取对象 - 更改对象属性,例如
myCar.Color="Green"
- 使用
ISession.Update(myCar)
将其提交回数据库
- Obtain the object from the database by using
ISession.Get(typeof(T), id)
- Change the object property, for example,
myCar.Color="Green"
- Commit it back to the database by using
ISession.Update(myCar)
myCar
未更新到数据库.但是,如果以后再调用ISession.Flush
,则会对其进行更新.
The myCar
is not updated to database. However, if I call ISession.Flush
afterwards, then it is updated.
何时使用Flush
,何时不使用它?
When to use Flush
, and when not to use it?
推荐答案
在许多情况下,您不必在意NHibernate刷新的时间.
In many cases you don't have to care when NHibernate flushes.
只有在创建自己的连接后才需要调用flush ,因为NHibernate不知道何时进行连接.
You only need to call flush if you created your own connection because NHibernate doesn't know when you commit on it.
对您来说真正重要的是交易.在事务期间,您与其他事务是隔离的,这意味着,当您从数据库中读取数据时,总会看到您的更改,而您看不到其他更改(除非已提交).因此,您无需担心NHibernate何时更新数据库中的数据(除非已提交).反正任何人都看不到.
What is really important for you is the transaction. During the transaction, you are isolated from other transactions, this means, you always see your changes when you read form the database, and you don't see others changes (unless they are committed). So you don't have to care when NHibernate updates data in the database unless it is committed. It is not visible to anyone anyway.
NHibernate刷新,如果
NHibernate flushes if
- 您称之为提交
- 在进行查询之前,以确保您按内存中的实际状态进行过滤
- 当您致电冲洗
示例:
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看到您的会话很脏,然后将更改刷新到数据库.仅当您在会话之外进行更改时,才需要更新并保存. (这意味着使用分离的实体,即会话不知道的实体.)
The entity is updated on commit. NHibernate sees that your session is dirty and flushes the changes to the database. You need update and save only if you made the changes outside of the session. (This means with a detached entity, that is an entity that is not known by the session).
性能说明:刷新不仅执行必需的SQL语句来更新数据库.它还搜索内存中的更改.由于POCO上没有脏标志,因此需要将会话中每个对象的每个属性与其第一级缓存进行比较.如果执行得太频繁,这可能会成为性能问题.您可以采取一些措施来避免性能问题:
Notes on performance: Flush not only performs the required SQL statements to update the database. It also searches for changes in memory. Since there is no dirty flag on POCOs, it needs to compare every property of every object in the session to its first level cache. This may become a performance problem when it is done too often. There are a couple of things you can do to avoid performance problems:
- 请勿循环刷新
- 避免序列化的对象(需要序列化才能检查更改)
- 在适当的情况下使用只读实体
- 在适当的情况下设置 mutable = false
- 在属性中使用自定义类型时,请实施有效的Equals方法
- 当您确定自己知道自己在做什么时,请小心禁用自动冲洗.
- Do not flush in loops
- Avoid serialized objects (serialization is required to check for changes)
- Use read-only entities when appropriate
- Set mutable = false when appropriate
- When using custom types in properties, implement efficient Equals methods
- Carefully disable auto-flush when you are sure that you know what you are doing.
这篇关于NHibernate Flush-如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!