【问题标题】:NHibernate doesn't save one property onlyNHibernate 不只保存一个属性
【发布时间】:2014-02-14 19:37:55
【问题描述】:

我正在尝试更新表中的单个列。没有发布任何更新(使用 SQL Profiler 检查)。没有错误。

  • 类映射有dynamic-update="true"
  • 没有在类上启用版本控制。
  • 刷新模式提交。
  • 属性映射没有任何插入/更新修饰符 (<property name="Deleted" />)。
  • 属性是自动实现的 (public virtual bool Deleted { get;set;})。
  • NH 3.3.0、.NET 4、x64。

    using (var transaction = this._session.BeginTransaction())
    {
        try
        {
            var order = this.session.Load<Order>(id);
            order.Deleted = true;
            this._session.Update(order);
            transaction.Commit();
        }
        catch (Exception)
        {
            transaction.Rollback();
            throw;
        }
    }
    

【问题讨论】:

  • 如果你在事务提交行中断,_session.IsDirty() 是真的吗? Deleted 是自动属性还是有支持字段?而且您不需要在会话中调用 Update,但我怀疑这是问题
  • 你也在使用版本控制吗?
  • 我们无法猜测Repository.Load 里面的内容。请将该行替换为var order = _session.Get&lt;Order&gt;(id)。这样,_session.Update 就不需要了。您也不必手动回滚事务。
  • @DiegoMijelshon 我的错,请参阅更新后的问题。 Get 的问题在于它执行查询以获取实体;我正在努力做到这一点,以便为单个列发出单个 UPDATE 而没有 SELECT。
  • 您使用两个不同的sessions(session_session)这一事实可能是问题的根源。

标签: c# sql .net nhibernate


【解决方案1】:

基于 cmets,您尝试做的是创建一个代理而不从数据库获取当前状态(使用 session.Load),然后发出动态更新。

这行不通。 NHibernate 不记录对属性的个别更改;相反,它:

  • 将被跟踪实体的当前状态与从数据库中检索到的属性值的快照进行比较。
  • 据此确定哪些实体是脏的(即有变化)
  • 它生成 SQL 更新语句。如果使用dynamic-update,它将只包含修改后的属性。

如果您使用session.Load,一旦您访问Deleted 属性,NH 就会从数据库中加载记录。无论您对已跟踪的实体使用session.Load 还是session.Getsession.Update 都是无操作的。

或者,如果您已经拥有所有订单属性的状态,则可以在不加载的情况下更新:

var order = GetTheOrderFromMemory();
order.Deleted = true;
session.Update(order);
transaction.Commit();

这将尊重dynamic-update,因为 NH 没有可与之比较的快照...

...这就是为什么 HQL 是对单个属性进行一次性更新的唯一方法。

【讨论】:

  • 不幸的是,情况似乎确实如此。我将坚持使用加载和更新(由于某种原因,它通过获取和更新开始工作——以前没有这样做过)。感谢您的帮助。
  • 很高兴听到。但是如上所述,如果您已经Loading,则不需要Update
猜你喜欢
  • 2016-11-07
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多