2010-11-05 86 views
4

我想知道什么样的最佳设计是用NHibernate持久化一个新的子实体,而不会意外覆盖数据库中的父项。NHibernate:如何保存一个新的实体,而不覆盖父:

我的问题是,孩子实体将是这个样子:

class Child 
{ 
    Parent Parent; 
    // other fields 
} 

我的问题是,孩子已经从UI层与母公司的ID一起提供,这意味着Parent ref基本上是未初始化的:它将填充ID,但其他一切都为空 - 因为填充其字段的唯一方法是额外往返数据库以读取它们。

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

回答

0

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

class Parent 
{ 

} 


class Child 
{ 
    Parent myParent; 
} 

,你试图设置家长和救孩子不有一个完整的父对象,只是ID。

你可以试试这个:

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

保存前,这应该告诉NHibernate的,有没有更改父对象持久化,它应该只看对象为ID坚持之间的关联父母和子女

1

您应该在进行保存(或SaveOrUpdates等)时使用聚合根(可能是Parent)。

为什么不干脆:

  • 使用从UI层
  • 在孩子有父ID取父对象的孩子加入到父母的孩子们收集
+0

好的谢谢。这意味着需要额外往返数据库才能获取父项,即使我并不打算对父数据执行任何操作,但我更愿意避免使用这些数据。没有什么好方法可以避免这种情况? – PhantomDrummer 2010-11-05 11:28:05

+0

建议使用Load()作为Trygve以避免加载不必要的数据。 – UpTheCreek 2010-11-05 12:03:23

+1

听起来似乎正在发生的事情是,孩子正在通过查询直接填充到用户界面中,而不考虑父母。正在提出的是一种设计的一般原则,即你从未在父母之外拥有子女。你肯定不会在没有经过父母的情况下添加新的孩子。 – Sisyphus 2010-11-05 12:29:43

3

您必须使用session.Load(parentid)来获取聚合根。与session.Get()方法不同,它实际上并不从数据库中获取任何数据,它只是实例化一个Parent代理对象,用于将Child对象添加到数据库中正确的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

+0

+1;有趣的链接,但我发现http://ayende.com/Blog/archive/2009/04/30/nhibernate-ndash-the-difference-between-get-load-and-querying-by.aspx更简洁的参考获取与负载的区别。 – Marijn 2010-11-05 12:50:52

+0

有趣,谢谢 – PhantomDrummer 2010-11-05 16:12:25

1

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

相关问题