19

在我的系统中,我有两个实体 - ShoppingCart 和 ShoppingCartItem。相当通用的用例。但是,当我保存我的 ShoppingCart 时,没有任何项目被保存到数据库中。

在我的对象中,我创建了一个新的 ShoppingCart 对象。

ShoppingCart cart = CreateOrGetCart();

然后,我将从数据库中获取的现有产品添加到开头。

cart.AddItem(product);

这只是将项目添加到 IList 的简单包装器。

    public virtual void AddItem(Product product)
    {
        Items.Add(new ShoppingCartItem { Quantity = 1, Product = product });
    }

然后我在存储库上调用 SaveOrUpdate

Repository.SaveOrUpdate(cart);

看起来像这样:

   public T SaveOrUpdate(T entity)
    {
        Session.SaveOrUpdate(entity);
        return entity;
    }

我正在使用 Fluent NHibernate 进行映射:

    public ShoppingCartItemMap()
    {
        WithTable("ShoppingCartItems");

        Id(x => x.ID, "ShoppingCartItemId");
        Map(x => x.Quantity);

        References(x => x.Cart, "ShoppingCartId").Cascade.SaveUpdate();
        References(x => x.Product, "ProductId");
    }


    public ShoppingCartMap()
    {
        WithTable("ShoppingCarts");

        Id(x => x.ID, "ShoppingCartId");
        Map(x => x.Created);
        Map(x => x.Username);

        HasMany<ShoppingCartItem>(x => x.Items)
            .IsInverse().Cascade.SaveUpdate()
            .WithKeyColumn("ShoppingCartId")
            .AsBag();
    }

数据库架构 (SQL Server 2005) 也相当通用:

CREATE TABLE [dbo].[ShoppingCarts]
(
[ShoppingCartID] [int] NOT NULL IDENTITY(1, 1),
[Username] [nvarchar] (50) NOT NULL,
[Created] [datetime] NOT NULL
)
GO
ALTER TABLE [dbo].[ShoppingCarts] ADD CONSTRAINT [PK_ShoppingCarts] PRIMARY KEY CLUSTERED ([ShoppingCartID])
GO



CREATE TABLE [dbo].[ShoppingCartItems]
(
[ShoppingCartItemId] [int] NOT NULL IDENTITY(1, 1),
[ShoppingCartId] [int] NOT NULL,
[ProductId] [int] NOT NULL,
[Quantity] [int] NOT NULL
)
GO
ALTER TABLE [dbo].[ShoppingCartItems] ADD CONSTRAINT [PK_ShoppingCartItems] PRIMARY KEY CLUSTERED ([ShoppingCartItemId])
GO
ALTER TABLE [dbo].[ShoppingCartItems] ADD CONSTRAINT [FK_ShoppingCartItems_Products] FOREIGN KEY ([ProductId]) REFERENCES [dbo].[Products] ([ProductId])
GO
ALTER TABLE [dbo].[ShoppingCartItems] ADD CONSTRAINT [FK_ShoppingCartItems_ShoppingCarts] FOREIGN KEY ([ShoppingCartId]) REFERENCES [dbo].[ShoppingCarts] ([ShoppingCartID])
GO

当我保存或更新我的 ShoppingCart 时,为什么没有任何 ShoppingCartItems 也被保存?

请帮忙。

谢谢

更新:将其包装在交易中,为我提供了更多信息:

无法将值 NULL 插入到列“ShoppingCartId”、表“WroxPizza.dbo.ShoppingCartItems”中;列不允许空值。插入失败。该语句已终止。

这是因为它是一辆新推车。

4

8 回答 8

3

I had this exact problem with fluent nhibernate. There appears to be a small bug in mapping one-to-many relationships and the relationships not automatically saving or cascading. See here for a posting about it on the Fluent NHibernate group.

Apparently, there is someone working on the issue!

I can;t say for sure that this is the issue with your code but it looks very similar to a problem I had. Hope that helps some!

于 2009-03-05T22:42:17.180 回答
2

你为什么包括.Cascade.SaveUpdate()在行中

References(x => x.Cart, "ShoppingCartId").Cascade.SaveUpdate()

?

也许它使 NHibernate(或 Fluent NHibernate)感到困惑,您的关系两端似乎存在级联保存/更新?

将您的 HasMany 配置为级联应该足以实现您想要的。

于 2009-02-13T12:58:33.013 回答
1

尝试将 Session.SaveOrUpdate 包装在事务中,或者直接在之后强制刷新。

于 2009-02-08T01:56:59.573 回答
0

我不确定,但我不认为 N​​Hibernate 将对象的保存级联到子对象。您没有显示调用 SaveOrUpdate 的代码,但我知道如果您此时遍历 ShoppingCartItems,分别保存每个,那么它们也会被持久化。

于 2009-02-08T02:00:23.733 回答
0

您的购物车物品是否有可能先保存,然后才是购物车?因此子项没有父 ID 可以使用?

您可能需要在创建时将购物车显式保存回数据库,然后将商品添加到其中并保存 - 只是为了获取 ID。

于 2009-02-08T12:37:35.380 回答
0

如前所述,您使用 Identity 定义(在数据库模式中)字段,因此,必须在 Map 文件中设置这些字段。示例如下:

Id(x => x.ID, "ShoppingCartItemId").GeneratedBy.Identity();

您收到的错误是因为您没有将映射中的 Identity 字段设置为由 Identity 生成,因此,当您尝试 Save() 时,不会生成 Identity 列(并且在数据库中设置为 not null)然后它给你错误。

于 2010-12-27T07:42:02.063 回答
-1

我对 NHibernate一无所知(我使用的 OPF 为我做这件事),但是当您保存聚合根(ShoppingCart)时,代码是否也应该将其复合拥有的实例提交给会话?

于 2009-02-08T12:32:22.927 回答
-4

问题在于您的 sessionfactory 配置语句。如果您希望您的数据保持不变,请不要使用 Exposeconfiguration。这肯定会解决您的数据持久性问题。

于 2009-03-13T11:04:47.103 回答