更新行李例外情况

我有这样的数据库表:


[表记录]


RecordId    MyColumn1   MyColumn2  

----------------------------------

112         somedata8   somedata7   

112         somedata6   somedata1   

148         somedata3   somedata5

[tbl记录水果]


RecordId    FruitTypeId  

-------------------------

  112         53  

  112         85  

  148         16  

[表水果类型]


FruitTypeId     Text  

----------------------

53              Apple  

85              Banana  

16              Orange  

以及对应的NHibernate映射:


<?xml version="1.0" encoding="utf-8"?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">

    <class name="Record, Infrastructure.Interface"

           table="tblRecord">

        <id name="Id" type="Int32" unsaved-value="null">

            <column name="RecordId" length="4" sql-type="int" not-null="true" unique="true" index="PK_tblRecord" />

            <generator class="native" />

        </id>

        ...

        <bag name="Fruits" table="tblRecordFruit" inverse="false" lazy="true" cascade="save-update">

            <key>

                <column name="RecordId" length="4" sql-type="int" not-null="true" />

            </key>

            <many-to-many

                class="FruitType, Infrastructure.Interface">

                <column name="FruitTypeId" length="2" sql-type="smallint" not-null="true" />

            </many-to-many>

        </bag>

        ...

    </class>

</hibernate-mapping>


<?xml version="1.0" encoding="utf-8"?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">

  <class name="FruitType, Infrastructure.Interface"

         table="tblFruitType"

         mutable="false"

         lazy="false">

    <id name="Id" type="Int16" unsaved-value="0">

      <column name="FruitTypeID" sql-type="smallint" not-null="true" unique="true" index="PK_Fruit" />

      <generator class="native" />

    </id>

    <property name="Text" type="String">

      <column name="Text" length="255" sql-type="varchar" not-null="true" />

    </property>

  </class>

</hibernate-mapping>


慕仙森
浏览 130回答 2
2回答

绝地无双

如果我理解正确,您正在尝试更新Record与会话断开连接的对象。因此您可以使用Merge会话重新连接。在这种情况下,为了使Merge您的集合工作,它们需要merge映射中的级联选项。因此,请尝试Fruits使用以下命令更新您的映射: cascade="merge,save-update"或简单地使用以下命令来更新您的映射cascade="all"以涵盖所有情况:<bag name="Fruits" table="tblRecordFruit" inverse="false" lazy="true" cascade="all">&nbsp; &nbsp; &nbsp; &nbsp;PS调用实际上应该与您现有的映射SaveOrUpdate一起正常工作。也许您在更新映射之前已经尝试过,否则请确保异常相同并提供.Fruitscascade="save-update"Fruit更新 1因此,如前所述,我假设您正在尝试更新分离的实体(从不同会话加载的实体)。请确认并提供详细信息到底是如何发生的?它是否从 UI 上显示的状态进行序列化/反序列化?在这种情况下,您应该意识到需要在保存对象后序列化状态。因为保存后Fruits集合类型更改为正确处理进一步更新所需的内部 NHibernate 集合。因此,当record.Fruits.Add(obj)调用现有Record对象时,它的类型record.Fruits一定不能List<T>是 NHibernate 类型(据说PersistangGenericType<T>)。因此,请确保您没有覆盖现有对象的集合属性:record.Fruits = new List<FruitType>();// WRONG for existing record...//Instead clear existing record collection:record.Fruits.Clear(); //Correct还要在调试器中进行以下检查://You somehow obtain record instance that you want to updatevar record = DeserializeOrLoadState(recordId);...//When you update existing recordrecord.Fruits.Add(fruitType1);// Make sure in debugger that for existing record record.Fruits is NHibernate type PesistentGenericBag<T> and not List<T>...//When you SaveOrUpdate/Merge existing recordsession.Merge(record);// <- make sure in debugger that for existing record.Fruits is NHibernate type PesistentGenericBag<T> and not List<T>...SerializeState(record);// serialize state only after session.SaveOrUpdate更新2它不是 PersistentGenericBag。这曾经有效。现在从 NHibernate v2 到 v4 的更改是否可能会导致此问题?我不知道它是如何在 NHibernate v2 中完成的 - 但它肯定可以在您的代码中修复。所以你需要调查为什么它仍然存在List——这表明你做错了什么。一些建议:1) 如果你的Fruits属性有 setter - 删除它以确保所有操作都是通过IList方法完成的:public class Record{&nbsp; &nbsp; public virtual IList<FruitType> Fruits {get; } = new List<FruitType>()}2)调查这部分Then the user opens that record again and adds another FruitType to it.。你还没说它是如何实现的。这里的UI <-> Entity 映射是如何实现的?当从数据库加载现有实体时,我很确定它不是ListNHibernate 类型。所以你应该调试并找到它更改为 的地方List。3) 还尝试将级联设置更改为cascade="all-delete-orphan"。我不认为这会改变任何事情——但以防万一。

白猪掌柜的

例外情况:违反主键约束“PK_tblRecordFruit_1”。无法在对象“dbo.tblRecordFruit”中插入重复的键。重复的键值为 (112, 53)。说违反了主键约束。这意味着您正在尝试复制主键列的值。查看映射中的以下代码块:<bag name="Fruits" table="tblRecordFruit" inverse="false" lazy="true" cascade="save-update">&nbsp; &nbsp; <key>&nbsp; &nbsp; &nbsp; &nbsp; <column name="RecordId" length="4" sql-type="int" not-null="true" />&nbsp; &nbsp; </key>看来这RecordId是你在桌子上的主键tblRecordFruit。如果是这种情况,很明显您无法将问题中提到的示例数据插入到表中:RecordId&nbsp; &nbsp; FruitTypeId-----------------------&nbsp; 112&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;53&nbsp; 112&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;85&nbsp; 148&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;16该值112不能在列中重复RecordId。如果您的代码尝试执行此操作,很明显您将得到您所说的异常。您是否正在寻找复合键(在 和RecordId列上FruitTypeId)?首先,需要注意的是:复合键在 NHibernate 中当然是可映射的,但它比典型的单个身份键要复杂一些。与普通密钥相比,有一些额外的设置工作,查询更加痛苦,并且它们在延迟加载方面往往不太优化。由于这些原因,经验丰富的 NHibernate 用户通常会尽可能避免使用复合键。......_<composite-id>&nbsp; &nbsp; <key-many-to-one class="SuperShop.Domain.OrderItemComponent,SuperShop.Domain" name="OrderItemComponent" column="OrderItemProductID" />&nbsp; &nbsp; <key-property name="DetailType" column="DetailTypeID" type="SuperShop.Domain.DetailTypes,SuperShop.Domain" /></composite-id><version name="LastModifiedOn"....
打开App,查看更多内容
随时随地看视频慕课网APP