我的情况与this question中描述的非常相似:
Engineer
和Manager
都来自Contact
,Engineer
可以升级(或降级,视您的观点而定)Manager
。
区别在于 - 我记录了联系人提交的所有订单
意思是 - 我的Contact
类有一个IList<Order> Orders
属性,可以包含100,000个订单。 (在你问之前 - 显然这个属性没有被加载到内存中,它只是Contact OrderSubmitter
的{{1}}属性的另一端。
我喜欢@Jamie Ide建议的'复制构造函数'的想法
问题是 - 我可以更改Order
对象的引用而不将它们加载到内存中吗?
[编辑]
是的,我可以使用HQL update
但是,这会产生一个不同的问题 - 我正在尝试创建一个实体,并让其他实体在同一个事务中引用它。意思是:
Order
但是,ExecuteUpdate会立即发生,而Manager manager = new Manager(engineer);
session.Save(manager);
session.CreateQuery("update Order set OrderSubmitter = :manager where OrderSubmitter = :engineer")
.SetParameter("manager",manager)
.SetParameter("engineer",engineer)
.ExecuteUpdate();
session.Transaction.Commit();
实体仅保存在“commit”上。
当然,这会导致外键异常
我可以在Manager
调用之后立即明确调用session.Flush()
来绕过它,但这似乎不是很好的做法。
任何想法?
答案 0 :(得分:1)
真正的问题是您的建模不正确。 在OO中,对象不会更改其类型。 经理/工程师应建模为一对一的关系。 您可以将作业类作为Employee的组件属性。 与员工从工程师晋升为经理相比,您只需要更换组件。此外 - 您不必更新订单表,因为提交者保持不变。唯一的区别是它的工作成分
答案 1 :(得分:0)
正如您所说,问题是ExecuteUpdate()立即发生,并且在插入新管理器后不会发出。我认为立即调用session.Flush()是正确的解决方案。您还应该删除同一事务中的原始工程师对象。
另请参阅this question的答案。