更新 nHibernate 中的 children 个值
Updating children values in nHibernate
我的数据库结构 invoice
和 invoiceParents
one-to-many
,inverse
等于 "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
我的数据库结构 invoice
和 invoiceParents
one-to-many
,inverse
等于 "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