2009-02-08 63 views
19

在我的系统中,我有两个实体 - ShoppingCart和ShoppingCartItem。相当通用的用例。但是,当我保存我的ShoppingCart时,没有任何项目正被保存到数据库中。NHibernate:使用流利Nhibernate保存子对象

在我的对象中,我创建了一个新的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; 
    } 

我使用功能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 

当我SaveOrUpdate我的购物车,为什么没有任何ShoppingCartItems也被保存?

请帮忙。

感谢

UPDATE: 结束语在交易providng我更多一些信息:

无法将NULL值插入列 'ShoppingCartId',表 “WroxPizza .dbo.ShoppingCartItems';列不允许有空值。 INSERT失败。该语句已终止。

这是因为它是一个新的购物车。

+0

James Gregorys解决方案为我工作。 – 2010-06-30 13:53:48

回答

1

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

0

我不确定,但我不认为NHibernate将对象的保存级联到子对象。你不会显示调用SaveOrUpdate的代码,但是我知道如果你在这一点上循环访问ShoppingCartItems,单独保存它们,然后它们也会被保存。

0

我知道什么约NHibernate的(最优潮流我用这是否对我来说),但不是它的情况下,当你保存聚合根(我的购物),该代码也应提交其复合地拥有实例的会议呢?

0

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

您可能需要在创建时明确地将购物车保存回数据库,然后将其添加到其中并保存 - 以获取该ID。

2

你为什么包括在该行

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

.Cascade.SaveUpdate()

也许它混淆了NHibernate(或流利NHibernate)似乎有级联保存/更新从你的关系两端?

配置你的HasMany级联应该足以实现你想要的。

-4

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

+0

使用schemaexport应该小心。 – 2009-03-14 12:47:22

0

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

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

由身份生成你得到,因为你没有设置标识字段映射中的错误,因此,当你试图保存(),身份列不会生成(并且在数据库中设置为非空值),那么它会给出错误。