首页 文章

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

提问于
浏览
0

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

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

我对Device / Intersection的映射如下:

<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(intersection)的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

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

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

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

相关问题