我在获取存储在另一个类中的一个类的列表时遇到了一些问题。
我有一个类交集,它是一个基本类型的设备,它包含一个区域列表,这是我的另一个类。每个交叉口可以有多个区域,但只有一个交集可以分配给特定的区域。
设备/交叉口的映射如下:
<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对象并将其保存到数据库中,那么一切都会保存得很好,并且要引用到交集对象的Intersection_Id字段与预期的一样为null。但是,一旦我将此Zone对象添加到交集并保存该交集,它就不会通过Intersection_id字段将区域链接到该交集,并且加载该交集在区域列表中不包含任何区域。
如果我在不首先保存区域的情况下保存该交叉口,则该交叉口保存良好,但不会保存该区域。
查看session.Save的SQL (交集),我没有看到任何试图保存区域的信息被发送。
另外,如果我保存了这个交集,然后尝试一个
foreach(Zone z in intersection.Zones) session.Save(z);
NHibernate不执行任何SQL,也不保存区域。
这可能是我错过的小东西。有什么想法吗?
编辑
我真的找到了解决这个问题的办法。这些映射实际上是正确的,或者至少我假设它们是正确的,因为它们看起来没有什么明显的错误,尽管我对NHibernate的了解还不足以确定这个解决方案为什么工作。
不管怎样,解决方案是三倍的。
首先,在保存包含区域的列表之前,我必须确保保存了区域。如果在调用以下所述的刷新时不保存区域,则当它试图将区域链接到交叉口时,会得到一个错误,但没有在区域的表中找到区域记录。
这是通过调用Session.Save(区域)实现的,其中会话是一个ISession。
在保存了区域之后,我使用上面的方法保存了交集,但是调用了Session.Save(交集)。
解决这个问题的最后一步是在我保存了交集之后,我必须为Session.Flush()调用ISession,然后该ISession将区域链接到该交叉口。
这解决了问题,现在一切都被保存、加载和正确链接。
ISession.Flush()在后台做了什么,要求我调用它来将所有的东西拼凑在一起,为什么它没有全部保存--简单地调用Session.Save(交叉),并设置为包设置级联?
发布于 2011-09-15 08:56:57
在NH中,更新和插入通常是在Session.Flush()上批处理和执行的,但是由于使用identity,NH必须立即发出INSERT来生成id,但是批量执行更新。为了提高性能和启用批处理,还有其他关键生成策略(GUID、HiLo、.)。
完全不插入区域可能会有帮助。
<bag name="Zones" cascade="all-delete-orphan" inverse="true">https://stackoverflow.com/questions/7403806
复制相似问题