【问题标题】:Can I manage the entity status in NHibernate?我可以在 NHibernate 中管理实体状态吗?
【发布时间】:2012-03-01 06:06:19
【问题描述】:

最近,我尝试在我的项目中使用 NHibernate。看下面的代码

var _sessionFactory = cfg.BuildSessionFactory();
        var _session = _sessionFactory.OpenSession();
        var user = new User() {UserName = "carl", Gender = 1};
        _session.Save(user);
        _session.Delete(user);
        _session.Flush();
        _session.Close();
        _sessionFactory.Dispose();

NHibernate 会将用户保存到数据库中,然后将其从数据库中删除。我知道代码有点奇怪,但我真的希望 NHibernate 知道你真的不需要访问 db 两次。实体框架会有所不同,它会在内存中切换用户对象的状态,当刷新时,它会访问数据库以持久化它。当然,状态标记为已删除的用户不会被持久化。所以这里不需要数据库访问。这就是我想要的!!

有没有人知道 NHibernate 有那个接口来改变像 EF 这样的实体状态?

【问题讨论】:

  • 用户类的映射是什么?它是否需要(假定的)id-key 的数据库往返?如果您知道要删除该对象,为什么还要保留它?为什么您认为单个数据库调用(删除)如此昂贵以至于您需要避免它?您是否尝试过使用您回滚的事务?

标签: c# nhibernate frameworks entity status


【解决方案1】:

将实体保存到数据库的原因可能是因为您可能正在使用身份 ID 生成,这会强制 NH 立即插入。如果您使用其他策略,例如 HiLo,您会看到预期的结果。

【讨论】:

  • 您对身份ID的看法是正确的!但是在我将其设置为 HiLo 策略后,NHibernate 仍然将其保存到 db 并从 db 中删除。原因是 NIBerate 会将所有动作保存到 ActionQueue 中。当您刷新会话时。它将拉动所有动作并调用它。我认为这不是最好的方法! NHibernate 应该跟踪实体的状态并决定是否保存它。
  • 我认为这背后的原因是,可能有触发器、nhibernate.envers 或其他想知道发生了什么的事情。如果您将其包装在事务中并回滚,则根本不会发送任何内容。
【解决方案2】:

首先身份 id 会触发数据库的插入,你没办法。但是,更改为 hi-lo 仍然不能保证不会发生插入。原因在于 NHibernate 从 NHibernateSessionFactory 生成的 ISession 和默认的 FlushMode。

请参阅 NHibernate 参考中的第 9.7 节,其中解释了 FlushMode 机制。对于您的情况,您应该将 FlushMode 设置为 Never (FlushMode.Never),这样就不会发生幕后刷新。

【讨论】:

  • 我试过 FlushMode.Never 并且它仍然保存/删除了两次数据库访问。我认为这正是 NHibernate 构建此功能的方式。可能无法摆脱我的代码中的数据库访问。 NHibernate 可以通过跟踪代码的每个操作而不是实体的最终状态来管理 ORM。换句话说。如果我像上面那样编写愚蠢的代码。 NHibernate 会像我一样愚蠢地遵循它。
猜你喜欢
  • 1970-01-01
  • 2019-02-23
  • 2021-05-26
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
  • 2021-07-29
  • 1970-01-01
  • 2015-09-03
相关资源
最近更新 更多