2009-04-21 46 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更新时。

无论如何:感谢您的帮助!

相关问题