2009-04-21 66 views
2

我使用最新的流利NHibernate庫(0.1.0.452),我有一個問題,保存子女實體。流利的NHibernate的HasMany不更新FK

我認爲這是相當常見的場景...我已經得到了與映射父:

HasMany<Packet>(x => x.Packets) 
      .Cascade.All() 
      .KeyColumnNames.Add("OrderId"); 

和一個簡單的包類(領域模型和FNH映射)沒有任何參考父母。 生成的內容是包含名爲OrderId的列的正確數據包表。 沒有用的是保存。 每當我嘗試保存父對象時,孩子也被保存,但FK保持不動。 我檢查了SQL,並在INSERT語句中OrderId甚至沒有出現!

INSERT INTO KolporterOrders (CargoDescription, SendDate, [more cols omitted]) VALUES ('order no. 49', '2009-04-22 00:57:44', [more values omitted]) 
SELECT LAST_INSERT_ID() 
INSERT INTO Packets (Weight, Width, Height, Depth) VALUES ('To5Kg', 1, 1, 1) 
SELECT LAST_INSERT_ID() 

正如您所看到的,OrderId在上一個INSERT中完全缺失。

我還檢查產生的NH映射,似乎它的確定:

<bag name="Packets" cascade="all"> 
    <key column="OrderId" /> 
    <one-to-many class="Company.Product.Core.Packet, Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
</bag> 

我試圖級聯設定爲不同的值。我甚至添加了對PacketMap(FNH映射類)的引用。

任何想法爲什麼OrderId沒有被插入?

編輯:忘記提及:如果它很重要,我使用MySQL5。

編輯2:上面的FNH映射生成hbm袋(不是一套) - 我編輯它。 用於保存的C#代碼:

var order = new Order(); 
NHSession.Current.SaveOrUpdate(order); //yes, order.Packets.Count == 1 here 

///Order.cs, Order ctor 
public Order() 
    { 
     CreateDate = DateTime.Now; 
     OrderState = KolporterOrderState.New; 
     Packets = new List<Packet>(); 
     Packets.Add(new Packet() 
     { 
      Depth = 1, 
      Height = 1, 
      Width = 1, 
      Weight = PacketWeight.To5Kg 
     }); 
    } 

會話被刷新,並在EndRequest關閉。

+0

請顯示負責創建和保存對象的C#代碼(失敗的代碼)。 – yfeldblum 2009-04-22 00:10:31

回答

0

在「vanilla」父子對象模型中,您必須更新子對象對父對象的引用,以便使NHibernate更新子對父對象的引用。

在「反轉」的父子對象模型中,您必須修改父對象的子對象集合,以便使NHibernate更新子對父對象的引用。

看來你可能想要使用「倒置」的父子對象模型。

在XML映射,需要

<set name="Packets" cascade="all" inverse="true"> 
    <key column="OrderId" /> 
    <one-to-many class="Company.Product.Core.Packet, Core, 
     Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
</set> 

在流利的映射,你需要

HasMany<Packet>(x => x.Packets) 
    .Cascade.All() 
    .Inverse() 
    .KeyColumnNames.Add("OrderId") 
; 
+0

這實際上是我嘗試的第一個變化。 它沒有解決問題。 [F] NH以某種方式忘記了OrderId。 – user87338 2009-04-22 00:05:48

+0

inverse = true讓NHibernate忽略這個關係。所以如果你沒有它,這將是產生錯誤的方法:-) – 2009-04-22 11:32:01

0

這是很奇怪的。你應該檢查後續的更新,NHibernate有時候會更新外鍵,然後它不會出現在插入中。

確保OrderId在數據包表上沒有多個含義。要檢查這一點,請將OrderId的名稱更改爲其他名稱。

級聯與它無關。它只控制是否需要明確保存子項。

2

好吧,我的錯。我在global.asax的ApplicationStart中測試它,所以請求沒有被創建,因此會話沒有被刷新。當我在一個簡單的ConsoleApp項目上測試它時,我意識到這一點,當我看到flushing actualy導致FK col更新時。

無論如何:感謝您的幫助!