更新父级时,NHibernate会更新所有子级

时间:2013-12-30 11:11:39

标签: hibernate nhibernate

用户拥有许多UserItem。

    [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属性或任何属性。

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

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

3 个答案:

答案 0 :(得分:0)

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

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

或者使用merge让nh为您处理

session.Update(session.Merge(item))

答案 1 :(得分:0)

使用级联类型作为选择

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

答案 2 :(得分:0)

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

  

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