帮助用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,也不保存区域。