nhibernate将实体从一种类型转换为另一种类型:如何处理集合?

时间:2011-08-07 12:36:47

标签: nhibernate hql

我的情况与this question中描述的非常相似:
EngineerManager都来自ContactEngineer可以升级(或降级,视您的观点而定)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()来绕过它,但这似乎不是很好的做法。

任何想法?

2 个答案:

答案 0 :(得分:1)

真正的问题是您的建模不正确。 在OO中,对象不会更改其类型。 经理/工程师应建模为一对一的关系。 您可以将作业类作为Employee的组件属性。 与员工从工程师晋升为经理相比,您只需要更换组件。此外 - 您不必更新订单表,因为提交者保持不变。唯一的区别是它的工作成分

答案 1 :(得分:0)

正如您所说,问题是ExecuteUpdate()立即发生,并且在插入新管理器后不会发出。我认为立即调用session.Flush()是正确的解决方案。您还应该删除同一事务中的原始工程师对象。

另请参阅this question的答案。