【问题标题】:How does NHibernate implement change tracking?NHibernate 如何实现变更跟踪?
【发布时间】:2010-05-28 07:40:46
【问题描述】:

nhibernate 代理是否有任何聪明的工作来提高更改跟踪的效率?还是它只支持实体框架所说的基于快照的更改跟踪?

【问题讨论】:

  • 您是在谈论审计日志、记录更改的位置,还是能够恢复到早期版本实体的完整更改管理?
  • 如果实体有多个属性 ORM 应该向数据库发出更新语句,只更改属性。在 LINQ TO SQL 中,它通过 INotifyPorpertyChanging/Changed 接口知道属性是否已更改(尽管这不是必需的,在这种情况下,它会退回到基于快照的更改跟踪,即比较每个属性以找出哪些属性已更改)。

标签: nhibernate


【解决方案1】:

它是基于快照的。

加载实体时,其状态作为对象[]存储在会话中。

刷新时,将当前状态转换为 object[] 并与原始状态进行比较以确定哪些属性是脏的。

由于许多原因,这更有效。其中之一是您不需要代理来跟踪更改。另一个是,如果您将属性设置为不同的值,然后将其还原,则该实体将被视为不脏,从而避免了不必要的 DB 调用。

【讨论】:

  • 为什么 NHibernate 不支持只更新修改的字段?如果快照已经存储,它可以很容易地识别修改的字段并且应该只更新那些。 IMO,它总是更新所有字段。你能解释一下吗?
  • @AmitJoshi 它确实支持它;这不是默认行为。您需要在实体映射中设置dynamic-update="true"
  • 为什么它不是默认行为?实际上,通过默认更新特定字段将生成更高效的查询。是不是因为dynamic-updatetrue 时跟踪每个属性的成本更高?
  • @AmitJoshi 这并不总是更有效,因为必须为每次更改生成update 语句,而不是在应用程序生命周期中生成一次。此外,您可能希望您的更改覆盖整个对象,而不是将您的更改与其他人的更改混合。一般来说,默认行为更容易预测,但您可以更改它。
【解决方案2】:

NHibernate 和 EntityFramework 以非常不同的方式跟踪变化。实体框架跟踪实体本身的变化。 NHibernate 跟踪会话中的变化。

跟踪实体中的更改需要更多内存(因为您要存储之前的值以及之后的值)。即使在与 ObjectContext 断开连接后,实体也可以保留更改跟踪。

在会话中跟踪更改总体上效率更高,但如果您断开实体与会话的连接,您将失去更改跟踪。

【讨论】:

  • 这个说法正确吗?据我所知,EF 使用所谓的更改跟踪器来跟踪实体更改。实体中不包含任何更改跟踪基础设施。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多