C# 更新nHibernate中的子项值
我的数据库结构是C# 更新nHibernate中的子项值,c#,nhibernate,C#,Nhibernate,我的数据库结构是invoice和invoiceParents的一对多,反向等于“false”和级联等于“全部删除孤立项”。下面是.hbm中针对家长和孩子的一些片段 家长: <id name="InvoiceId" column="INVOICEKEYID" unsaved-value="0"> <generator class="sequence"> <param name="sequence">SOME_SEQ</param>
invoice
和invoiceParents
的一对多
,反向
等于“false”
和级联
等于“全部删除孤立项”
。下面是.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为空;对于invoicePartners,有after it UPDATE语句,其中fk为正确的fk。直到现在一切都很好。
当我想更新时,只有invoicePartners的INSERT,invoice的一个更新。invoicePartners没有更新、删除和插入。
我在vs输出中观看它。
nHibernate是如何工作的?首先,我应该删除合作伙伴,然后插入新的合作伙伴,否则nHibernate将自动更新它?这一切都源于您创建的拥有
包(inverse=“false”
)。作为一般规则,切勿创建拥有的行李,带有(reverse=“true”
)的行李提供了最终性能,因为操作不会失败
在这种情况下,我会小心不要导致PK冲突,NHibernate不会处理插入PK冲突的情况,因为您告诉它这是一个包,而不是集。如果您没有PK,并且想要重复的invoicePartner
s,则继续使用包
,如果您没有,则切换到设置
。显然,如果您的类在内部确保了这一点,那么您将避免这个问题
不过,通常要小心使用bag
,我认为您在这种情况下没有问题,因为可以识别映射的实体,因此您应该获得与集
类似的性能。但如果无法识别,则NHibernate必须删除所有子项,并在任何集合更改时重新插入所有子项
将发票合作伙伴
添加到发票
时:
invoicePartner
不会保存关系,因为您已经告诉映射您希望invoice
拥有它
因此,在对数据库进行任何插入或更新时,invoicePartner
无法填写INVOICEKEYID
列
因此,父级invoice
等待数据库中存在invoicePartner
,然后更新外键列,如您所观察到的
根据默认行为,此更新可能完全是浪费时间,因为在我看来,孩子已经在保存此外键了
更新invoicePartner
集合时:
你说的不太合适。如果您所做的只是更改invoiceParnter
集合,则NHibernate将不会为invoice
调用update。发票
表中没有要更新的内容
cascade=“all delete orphan”
将确保父级保持集合与自身同步,只要更改集合后保存或更新父级,它将相应地插入、更新和删除invoicePartner
表中的行
但是您应该在父级行李上设置inverse=“true”
,并将inverse=“false”
添加到invoicePartner
多对一地图中。完成此操作后,检查我在第3段中提到的情况,其中NHibernate无法识别实体,并确保它确实通过其标识符关联了invoicePartners
,并有效地进行更改
参考: