更新 nHibernate 中的 children 个值

Updating children values in nHibernate

我的数据库结构 invoiceinvoiceParents one-to-manyinverse 等于 "false"cascade 等于 "all-delete-orphan".下面是 .hbm 中 parent 和 children 的一些片段。

Parent:

<id name="InvoiceId" column="INVOICEKEYID" unsaved-value="0">
   <generator class="sequence">
   <param name="sequence">SOME_SEQ</param>
   </generator>
</id>
...
<bag name="Partners" table="PARTNER" cascade="all-delete-orphan" inverse="false" lazy="true">
      <key column="INVOICEKEYID"/>
      <one-to-many class="Partner"/>
</bag>

Children:

<id name="Id" column="PARTNERKEYID" unsaved-value="0">
  <generator class="sequence">
     <param name="sequence">ANOTHER_SEQ</param>   
  </generator> 
</id>
...
<many-to-one name="Invoice" column="INVOICEKEYID" class="Invoice" />

当我首先创建 saveOrUpdate(invoice) 时,有 INSERT 语句,用于 invoice 和 invoicePartners,fk 为空,然后是 UPDATE 语句,用于 invoicePartners,具有正确的 fk。直到此时一切正常。 当我想更新时,invoicePartners 只有 INSERT,invoice 有一个 UPDATE。 invoicePartners 没有 UPDATE 或 DELETE AND INSERT。 我在 vs 输出中观看它。 nHibernate 是如何工作的?首先我应该删除合作伙伴然后插入新的或者 nHibernate 会自动更新它?

这一切都源于您所创造的拥有bag (inverse="false")。作为一般规则,永远不要创建拥有包,bag 和 (inverse="true") 提供最终性能,因为操作不会失败。

在这种情况下,我会小心不要以违反 PK 的方式结束,NHibernate 不会处理您插入违反 invoicePartner 的 PK 的情况,因为您已经告诉它是 bag 而不是 set。如果你没有 PK 并且想要重复的 invoicePartner,那么继续 bag,如果你没有,切换到 set。显然,如果您的 class 在内部确保这一点,那么您将避免这个问题。

不过一般要小心 bag,我认为你在这种情况下没问题,因为可以识别映射的实体,所以你应该获得与 set 相似的性能。但是,如果无法识别它们,那么 NHibernate 将不得不在任何 collection 更改时删除所有 children 和 re-insert 它们!


invoicePartner 添加到 invoice

invoicePartner 不会保存关系,因为您已经告诉映射您希望 invoice 拥有它。

因此,在对数据库进行任何插入或更新时,invoicePartner 无法填充 INVOICEKEYID 列。

所以 parent invoice 一直等到 invoicePartner 存在于数据库中,然后更新外键列,正如您观察到的那样。

根据默认行为,此更新可能完全是浪费时间,因为在我看来 child 本身已经保存了这个外键!


更新 invoicePartner collection:

你说的不太对。如果您所做的只是更改 invoiceParnter collection,NHibernate 将不会为 invoice 调用更新。 invoice table!

上没有什么可更新的

cascade="all-delete-orphan" 将确保 parent 保持 collection 与自身同步,它将插入、更新和删除来自 invoicePartner [=85= 的行] 因此,只要您在更改 collection 后保存或更新 parent!

但是你应该在 parent bag 上设置 inverse="true" 并在 invoicePartner many-to-one 地图上添加 inverse="false"。这样做之后,检查我在第 3 段中提到的情况,其中 NHibernate 无法识别实体,并确保它确实通过它们的标识符关联 invoicePartners 并有效地进行更改。


参考:http://nhibernate.info/doc/nhibernate-reference/example-parentchild.html