用户拥有许多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。新会话不会跟踪用户实例的更改。那我该怎么办?
答案 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()
。