流利的NHibernate HasMany没有更新FK

时间:2009-04-21 23:44:36

标签: nhibernate fluent-nhibernate nhibernate-mapping

我正在使用最新的Fluent NHibernate lib(0.1.0.452),我在保存子权限方面遇到了问题。

我认为这是相当常见的情况......我有一个父映射:

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

和一个简单的Packet类(在域模型和FNH映射中)没有对父级的任何引用。 生成的是一个正确的Packets表,其中包含一个名为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()

如您所见,最后一次INSERT中完全缺少OrderId。

我还检查了生成的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>

我尝试将Cascade设置为不同的值。我甚至在PacketMap(FNH映射类)中添加了引用。

为什么没有插入OrderId的想法?

编辑:忘了提及:如果重要的话,我正在使用MySQL5。

Edit2:上面的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上刷新并关闭。

3 个答案:

答案 0 :(得分:2)

好的,我的错。我在global.asax的ApplicationStart中测试它,因此尚未创建Request,因此会话未被刷新。当我在一个简单的ConsoleApp项目上测试它时,我意识到它,当我看到刷新实际导致FK col更新。​​

无论如何:谢谢你的帮助!

答案 1 :(得分: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>

在Fluent映射中,您需要

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

答案 2 :(得分:0)

这真的很奇怪。您应该检查后续更新,NHibernate有时会更新外键,然后它不会出现在插入中。

确保OrderId在Packets表上没有多种含义。要检查这一点,请将OrderId的名称更改为其他名称。

级联与它无关。它仅控制您是否需要明确保存子项。

相关问题