c# - 在 nHibernate 中更新子值
问题描述
我有数据库结构invoice
和invoiceParents
with one-to-many
,inverse
equals"false"
和cascade
equals "all-delete-orphan"
。下面是父母和孩子的一些片段.hbm
。
家长:
<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>
孩子们:
<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)
时,对于 invoice 和 invoicePartners 有 INSERT 语句,fk 为空,之后是 UPDATE 语句,invoicePartners 有正确的 fk。直到此时一切正常。当我想更新时,只有 INSERT 用于 invoicePartners,一个 UPDATE 用于发票。invoicePartners 没有更新或删除和插入。我在 vs 输出中观看它。nHibernate 是如何工作的?首先我应该删除合作伙伴,然后插入新的合作伙伴,否则 nHibernate 会自动更新它?
解决方案
这一切都源于您创建的拥有bag
( )。inverse="false"
作为一般规则,永远不要创建拥有包,bag
with ( inverse="true"
) 提供最终性能,因为操作不会失败。
在这种情况下,我会小心不要最终导致 PK 违规,NHibernate 不会处理您插入 PK 违规的情况invoicePartner
,因为您已经告诉它它是 abag
而不是 a set
。如果您没有 PK 并且想要重复invoicePartner
的 s,则继续使用bag
,如果没有,请切换到set
。显然,如果您class
在内部确保这一点,那么您将避免这个问题。
不过一般要小心bag
,我认为在这种情况下你很好,因为可以识别映射的实体,所以你应该得到与 a 类似的性能set
。但是如果它们不能被识别,那么 NHibernate 将不得不删除所有的子节点并在任何集合更改时重新插入它们!
在将 an 添加invoicePartner
到 an 时invoice
:
invoicePartner
不会保存关系,因为您已经告诉映射您希望拥有invoice
它。
因此,在对数据库进行任何插入或更新时,invoicePartner
都无法填写该INVOICEKEYID
列。
因此,正如您所观察到的,父invoice
级等到invoicePartner
数据库中存在,然后更新外键列。
根据默认行为,此更新可能完全是浪费时间,因为在我看来,孩子已经自己保存了这个外键!
在更新invoicePartner
集合时:
你说的真的不合适。invoice
如果您所做的只是更改invoiceParnter
集合,NHibernate 将不会调用更新。桌子上没有什么要更新的invoice
!
将cascade="all-delete-orphan"
确保父级保持集合与自身同步,invoicePartner
只要您在更改集合后保存或更新父级,它就会相应地插入、更新和删除表中的行!
但是您应该inverse="true"
在父级上设置bag
并添加inverse="false"
到invoicePartner
many-to-one
地图中。完成此操作后,检查我在第 3 段中提到的情况,即 NHibernate 无法识别实体,并确保它确实invoicePartners
通过它们的标识符关联并有效地进行更改。
参考: http: //nhibernate.info/doc/nhibernate-reference/example-parentchild.html
推荐阅读
- vbscript - 尝试将电子邮件从收件箱移动到子文件夹时出错
- node.js - 如何在 nodejs 代码中定义二进制类型“01”数据变量?
- python-3.x - 无法使用美汤提取网页数据
- c++ - 如何追踪导致 Segfault 的原因?
- css - React Native(仅限 Android)- Scrollview 被绝对视图重叠
- android - AndroidJUnit4.class 已弃用:如何使用 androidx.test.ext.junit.runners.AndroidJUnit4?
- javascript - 在 Angular 6 组件中使用外部 js 文件
- r - 箱线图重叠文本和点
- python - 查找列表中列表之间的最大减法绝对值
- python - 将图像转换为二进制后无法使用 matplotlib 在笔记本中显示