亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

更新行李例外情況

更新行李例外情況

C#
慕仙森 2023-08-20 15:50:28
我有這樣的數據庫表:[表記錄]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>
查看完整描述

2 回答

?
絕地無雙

TA貢獻1946條經驗 獲得超4個贊

如果我理解正確,您正在嘗試更新Record與會話斷開連接的對象。因此您可以使用Merge會話重新連接。


在這種情況下,為了使Merge您的集合工作,它們需要merge映射中的級聯選項。因此,請嘗試Fruits使用以下命令更新您的映射: cascade="merge,save-update"或簡單地使用以下命令來更新您的映射cascade="all"以涵蓋所有情況:


<bag name="Fruits" table="tblRecordFruit" inverse="false" lazy="true" cascade="all">       

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 update

var record = DeserializeOrLoadState(recordId);


...//When you update existing record

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

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

{

    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"。我不認為這會改變任何事情——但以防萬一。


查看完整回答
反對 回復 2023-08-20
?
白豬掌柜的

TA貢獻1893條經驗 獲得超10個贊

例外情況:


違反主鍵約束“PK_tblRecordFruit_1”。無法在對象“dbo.tblRecordFruit”中插入重復的鍵。重復的鍵值為 (112, 53)。


說違反了主鍵約束。這意味著您正在嘗試復制主鍵列的值。


查看映射中的以下代碼塊:


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

看來這RecordId是你在桌子上的主鍵tblRecordFruit。如果是這種情況,很明顯您無法將問題中提到的示例數據插入到表中:


RecordId    FruitTypeId

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

  112         53

  112         85

  148         16

該值112不能在列中重復RecordId。如果您的代碼嘗試執行此操作,很明顯您將得到您所說的異常。


您是否正在尋找復合鍵(在 和RecordId列上FruitTypeId)?


首先,需要注意的是:復合鍵在 NHibernate 中當然是可映射的,但它比典型的單個身份鍵要復雜一些。與普通密鑰相比,有一些額外的設置工作,查詢更加痛苦,并且它們在延遲加載方面往往不太優化。由于這些原因,經驗豐富的 NHibernate 用戶通常會盡可能避免使用復合鍵。

......

_


<composite-id>

    <key-many-to-one class="SuperShop.Domain.OrderItemComponent,SuperShop.Domain" name="OrderItemComponent" column="OrderItemProductID" />

    <key-property name="DetailType" column="DetailTypeID" type="SuperShop.Domain.DetailTypes,SuperShop.Domain" />

</composite-id>

<version name="LastModifiedOn"....


查看完整回答
反對 回復 2023-08-20
  • 2 回答
  • 0 關注
  • 173 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號