帮助用NHibernate映射一个包,没有保存的包里的物品

时间:2011-09-13 14:46:24

标签: nhibernate nhibernate-mapping

我在获取存储在另一个类中的某个类的List时遇到了一些麻烦。

我有一个Class Intersection,它是一个基本类型的设备,包含一个区域列表,另一个类别。每个交叉点可以有多个区域,但只有1个交叉点可以分配给特定区域。

我的设备/交叉点的映射如下:

<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>

我对Zone类的映射如下:

<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对象的Intersection_Id字段按预期为空。但是,一旦我将此区域对象添加到交叉点并保存交叉点,它就不会通过Intersection_id字段将区域链接到交点,并且加载交点不包含区域列表中的任何区域。

如果我在没有先保存区域的情况下保存交叉点,则交点保存正常,但不保存区域。

查看session.Save(十字路口)的SQL,我没有看到任何被发送的东西试图保存区域。

此外,如果我保存交叉路口,请尝试

foreach(Zone z in intersection.Zones) session.Save(z);

NHibernate不执行任何SQL,也不保存区域。

这可能是我想念的小事。有什么想法吗?

修改

我实际上找到了解决方法。这些映射实际上是正确的,或者至少我假设它们是因为它们看起来没有任何明显的错误,尽管我不太了解NHibernate来确定这个解决方案的工作原理。

无论如何,解决方案是三倍。

首先,我必须确保在使用包含区域的列表保存交叉点之前保存区域。如果在调用Flush时没有保存区域(如下所述),则在尝试将区域链接到交叉点但是没有在区域的表中找到区域记录时会出现错误。

这是通过调用Session.Save(区域)完成的,其中Session是一个ISession。

保存区域后,我使用上述方法保存了交叉点,但调用了Session.Save(交集)。

解决问题的最后一点是在我保存交叉点之后,我不得不为ISession调用Session.Flush(),然后将区域链接到交叉点。

这解决了问题,现在一切都得到了保存,加载和正确链接。

ISession.Flush()在后台做了什么,要求我把它拼凑起来,为什么不是全部保存只是调用Session.Save(交集)与包的级联设置是问题?

1 个答案:

答案 0 :(得分:0)

NH更新和插入中的

通常在Session.Flush()上进行批处理并执行,但由于您正在使用identity NH必须立即发出INSERT以生成ID,但批量更新。为了提高性能并启用批处理,还有其他密钥生成策略(GUID,HiLo,...)。

根本没有插入这些区域inverse可能有帮助

<bag name="Zones" cascade="all-delete-orphan" inverse="true">