帮助用NHibernate映射包,包中的项目不保存
我在获取存储在另一个类中的一个类的列表时遇到一些问题 我有一个类交叉点,它是一个基本类型的设备,包含一个区域列表,我的另一个类。每个交叉口可以有多个分区,但只能将一个交叉口指定给特定分区 我的设备/交叉点映射如下:帮助用NHibernate映射包,包中的项目不保存,nhibernate,nhibernate-mapping,Nhibernate,Nhibernate Mapping,我在获取存储在另一个类中的一个类的列表时遇到一些问题 我有一个类交叉点,它是一个基本类型的设备,包含一个区域列表,我的另一个类。每个交叉口可以有多个分区,但只能将一个交叉口指定给特定分区 我的设备/交叉点映射如下: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> <class xmlns="urn:nhibernate-mapping-2.2" name="EMTRAC.Devices.Device, EMTRAC_
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="EMTRAC.Devices.Device, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Device`" lazy="false">
<id name="PK" type="System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="PK" />
<generator class="identity" />
</id>
<many-to-one class="EMTRAC.Connections.Connection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="LocalConnection" lazy="false" cascade="all">
<column name="LocalConnection_id" />
</many-to-one>
<many-to-one class="EMTRAC.Connections.Connection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Connection" lazy="false" cascade="all">
<column name="Connection_id" />
</many-to-one>
<many-to-one class="EMTRAC.Packets.Packet, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Configuration" lazy="false" cascade="all">
<column name="Configuration_id" />
</many-to-one>
<joined-subclass name="EMTRAC.Intersections.Intersection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" lazy="false">
<key>
<column name="Device_id" />
</key>
<bag name="Zones" cascade="all-delete-orphan">
<key>
<column name="Intersection_id" />
</key>
<one-to-many class="EMTRAC.Zones.Zone, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</bag>
<many-to-one class="EMTRAC.Intersections.Streets, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Streets" lazy="false" cascade="all">
<column name="Streets_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Position" lazy="false" cascade="all">
<column name="Position" />
</many-to-one>
</joined-subclass>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="EMTRAC.Zones.Zone, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Zone`" lazy="false">
<id name="ID" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="PK" />
<generator class="identity" />
</id>
<property name="Active" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Active" />
</property>
<property name="Dir" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Dir" />
</property>
<property name="IntID" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="IntID" />
</property>
<property name="Width" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Width" />
</property>
<many-to-one class="EMTRAC.Headings.Heading, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Heading" cascade="all">
<column name="Heading_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Start" cascade="all">
<column name="Start_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Finish" cascade="all">
<column name="Finish_id" />
</many-to-one>
我对Zone类的映射如下所示:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="EMTRAC.Devices.Device, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Device`" lazy="false">
<id name="PK" type="System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="PK" />
<generator class="identity" />
</id>
<many-to-one class="EMTRAC.Connections.Connection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="LocalConnection" lazy="false" cascade="all">
<column name="LocalConnection_id" />
</many-to-one>
<many-to-one class="EMTRAC.Connections.Connection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Connection" lazy="false" cascade="all">
<column name="Connection_id" />
</many-to-one>
<many-to-one class="EMTRAC.Packets.Packet, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Configuration" lazy="false" cascade="all">
<column name="Configuration_id" />
</many-to-one>
<joined-subclass name="EMTRAC.Intersections.Intersection, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" lazy="false">
<key>
<column name="Device_id" />
</key>
<bag name="Zones" cascade="all-delete-orphan">
<key>
<column name="Intersection_id" />
</key>
<one-to-many class="EMTRAC.Zones.Zone, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</bag>
<many-to-one class="EMTRAC.Intersections.Streets, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Streets" lazy="false" cascade="all">
<column name="Streets_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Position" lazy="false" cascade="all">
<column name="Position" />
</many-to-one>
</joined-subclass>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="EMTRAC.Zones.Zone, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Zone`" lazy="false">
<id name="ID" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="PK" />
<generator class="identity" />
</id>
<property name="Active" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Active" />
</property>
<property name="Dir" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Dir" />
</property>
<property name="IntID" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="IntID" />
</property>
<property name="Width" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Width" />
</property>
<many-to-one class="EMTRAC.Headings.Heading, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Heading" cascade="all">
<column name="Heading_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Start" cascade="all">
<column name="Start_id" />
</many-to-one>
<many-to-one class="EMTRAC.Positions.Position, EMTRAC_v3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Finish" cascade="all">
<column name="Finish_id" />
</many-to-one>
现在,如果我创建一个区域对象并将其保存到数据库中,所有内容都保存得很好,并且引用交叉点对象的交叉点Id字段如预期的那样为空。但是,将此分区对象添加到交叉点并保存交叉点后,它不会通过“交叉点id”字段将分区链接到交叉点,并且加载交叉点不会在分区列表中包含任何分区
如果我在未首先保存分区的情况下保存交叉点,则交叉点可以很好地保存,但分区不会保存
查看session.Saveintersection的SQL,我没有看到任何试图保存区域的内容
此外,如果我保存交叉点,请尝试 foreachZone z位于intersection.Zones session.Savez NHibernate不执行任何SQL,也不保存区域 可能是我遗漏了一些小东西。有什么想法吗 编辑 我真的找到了解决办法。这些映射事实上是正确的,或者至少我假设它们是正确的,因为它们看起来没有明显的错误,尽管我对NHibernate了解不够,无法确定这个解决方案为什么有效 无论如何,解决方案有三个方面 首先,我必须确保在保存包含该区域的列表的交叉点之前保存该区域。如果调用刷新时未保存分区(如下所述),则当尝试将分区链接到交叉点,但未在分区的表中找到分区记录时,会出现错误 这是通过调用Session.Savezone完成的,其中Session是一个ISession 保存区域后,我使用上述方法保存交叉点,但调用Session.savecrossion 解决问题的最后一点是,在我保存交叉口后,我必须调用Session.Flush以获取ISession,然后将区域链接到交叉口 这解决了问题,现在所有内容都已正确保存、加载和链接
ISession.Flush在后台做什么,需要我调用它来将所有内容组合在一起,为什么不通过调用Session来保存所有内容。问题是Saveintersection与包的级联集?在NH中,更新和插入通常在Session.Flush上批处理和执行,但由于您使用的是identity NH,因此必须立即发出INSERT以生成id,但需要批量更新。为了提高性能并启用批处理,还有其他密钥生成策略GUID、HiLo等 完全不插入分区可能会有所帮助
<bag name="Zones" cascade="all-delete-orphan" inverse="true">
映射似乎很好。有例外吗?没有,我保存交叉点时,它只是没有将交叉点引用到区域,如果我没有先保存区域,则区域根本不会保存到区域表中。查看调用会话时执行的SQL。Saveintersection,NHibernate根本没有试图保存或更改区域。有什么想法吗?另外,如果我保存了交叉点,那么在crossion.Zones会话中尝试foreachZone z。Savez不执行任何SQL,也不保存区域。