NHibernate:如何在不覆盖父节点的情况下保存新实体:

时间:2010-11-05 10:44:08

标签: nhibernate

我想知道使用NHibernate持久化新的子实体而不会意外地覆盖数据库中的父实体的最佳设计是什么。

我遇到的问题是子实体看起来像这样:

class Child
{
    Parent Parent; 
    // other fields
}

我的问题是,子层已经从UI层提供了父级的ID,这意味着父级基本上没有初始化:它将填充ID但其他所有内容都为null - 因为唯一的方法填充其字段将是数据库的额外往返,以便阅读它们。

现在如果我在NHibernate上调用Session.SaveOrUpdate(child),那么父母会发生什么。我不希望NHibernate级联保存未初始化的父级,因为这只会破坏数据库中的数据。人们将如何解决这个问题?任何最佳做法?

4 个答案:

答案 0 :(得分:3)

您必须使用session.Load(parentid)来获取聚合根。与session.Get()方法相比,这实际上并不从数据库中获取任何数据,它只是实例化用于将Child对象添加到DB中正确的Parent的Parent代理对象(例如,正确获取外键)

您的代码可能类似于:

// Set the Parent to a nhibernate proxy of the Parent using the ParentId supplied from the UI
childFromUI.Parent = Session.Load<Parent>(childFromUI.Parent.Id);
Session.Save(childFromUI);

This article explains Get/Load and the nhibernate caches really well

答案 1 :(得分:1)

在执行保存(或SaveOrUpdates等)时,您可能应该使用聚合根(可能是父组件)。

为什么不呢:

  • 使用您在UI层中的子级中的父ID
  • 获取父对象
  • 将孩子添加到父母的子女集合

答案 2 :(得分:1)

我认为您必须概述nhibernate的映射配置。如果您已经将孩子的参考定义为父母,那么你必须全部加入Cascade,它会更新它! 所以,如果你说 Cascade.None ,他什么也不做。所有其他都是坏主意。因为你已经拥有了这个父母的信息。那么为什么要阅读db agane?!

答案 3 :(得分:0)

如果您的模型看起来像这样

class Parent 
{

}


class Child
{
     Parent myParent;
}

并且您正在尝试设置父级并保存子级而没有完整的父对象,只有ID。

你可以试试这个:

session.Lock(child.myParent, LockMode.None); 

在保存之前,这应该告诉nhibernate没有对父对象的更改进行持久化,它应该只查看Id的对象以保持父和子之间的关联