【问题标题】:NHibernate updates all children when I update the parent当我更新父级时,NHibernate 会更新所有子级
【发布时间】:2013-12-30 11:11:39
【问题描述】:

用户拥有许多 UserItems。

    [Set(0, Cascade = "all-delete-orphan", Lazy = CollectionLazy.False)]
    [Key(1, Column = "user_id")]
    [OneToMany(2, ClassType = typeof(UserItem))]
    public virtual ISet<UserItem> Items { get { return _items; } set { _items = value; } }

每个 UserItem 都有一个对 User 的引用:

    [ManyToOne(Name = "User", Lazy = Laziness.False, Column = "user_id")]
    protected virtual User User { get; set; }

问题是,当我只修改用户属性并更新它时,nh 会为每个 UserItem 生成更新查询。我不会更改 Items 属性或任何孩子的任何属性。

nh 不应该正确跟踪这样的变化吗?我希望在更新父级时只更新更改的子级。

更新
我想我明白为什么它对我不起作用,但我不知道如何解决它。当他连接时,我将用户实体保存在内存中。我不能使用一个会话对用户进行所有操作(因为可能有数千个连接的用户)。所以我打开会话,获取用户并关闭会话。然后我对用户进行一些更改,再次打开会话并调用更新。新会话不会跟踪该用户实例更改。那我该怎么办?

【问题讨论】:

  • 请提供一个工作示例来重现它。我无法使用提供的代码重现它...

标签: hibernate nhibernate


【解决方案1】:

您的问题(更新部分)的答案是9.4.2. Updating detached objects。有SaveOrUpdate()Merge()方法的详细解释。 Merge 将解决您的问题,摘录:

...使用Merge(Object o)此方法复制给定的状态 对象复制到具有相同标识符的持久对象上。 如果存在 当前没有与会话关联的持久实例,它 将被加载。该方法返回持久实例。如果 给定实例未保存或在数据库中不存在, NHibernate 将保存它并将其作为新的持久实例返回。 否则,给定的实例不会与 会议。 在大多数具有分离对象的应用程序中,您都需要 方法,SaveOrUpdate()Merge()

【讨论】:

    【解决方案2】:

    使用 Cascade 类型作为 Select

     [ManyToOne(Name = "User", Lazy = Laziness.False, Column = "user_id",cascade=CascadeType.SELECT)]
    protected virtual User User { get; set; }
    

    【讨论】:

      【解决方案3】:

      如果您有一个与其会话分离的实体,您是对的,更改跟踪无法正常工作。

      要再次更新它,您必须通过 Id 通过session.Get(...) 再次获取实体(您应该拥有 Id,因为您在内存中拥有带有 Id 的对象... 然后对该 new 对象进行更改并调用session.Update

      或使用merge 让 nh 为您处理

      session.Update(session.Merge(item))
      

      【讨论】:

      • 我可以使用 Merge() 吗?我有一个分离的用户实体,对其进行更改,然后创建一个新会话,启动事务,调用 session.Merge(user) 并提交,它会正常工作吗?
      • 是的,合并或多或少是为了处理这个问题。请记住,合并只是返回合并的对象。
      猜你喜欢
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-19
      • 2014-09-02
      • 1970-01-01
      • 2015-03-17
      相关资源
      最近更新 更多