2009-02-08 6 views
19

В моей системе у меня есть две сущности - ShoppingCart и ShoppingCartItem. Довольно общий прецедент. Однако, когда я сохраняю свой ShoppingCart, ни один из элементов не сохраняется в БД.NHibernate: Использование Fluent 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

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 

Когда я SaveOrUpdate мой ShoppingCart, почему нет никаких ShoppingCartItems также сохраняются?

Пожалуйста, помогите.

Благодаря

Бен

UPDATE: Подведем в сделке providng меня с некоторыми более подробной информации:

Не удается вставить значение NULL в столбце 'ShoppingCartId', таблица «WroxPizza .dbo.ShoppingCartItems'; столбец не допускает нулей. INSERT не работает. Заявление было прекращено.

Это потому, что это новая тележка.

+0

Решение Джеймса Грегориса работало для меня. –

ответ

1

Попробуйте обернуть Session.SaveOrUpdate в транзакции или заставить флеш сразу после.

0

Я не уверен, но я не думаю, что NHibernate каскадирует сохранение объектов дочерним объектам. Вы не показываете код, который вызывает SaveOrUpdate, но я знаю, что если вы зацикливаете объекты ShoppingCartItems в этот момент, сохраняя их индивидуально, они также будут сохранены.

0

Я не знаю ничего о NHibernate (БКП я использую это делает для меня), но это не тот случай, когда вы сохраняете совокупный корень (ShoppingCart), что код должен фиксировать свои композитно принадлежащие экземпляров к сессия тоже?

0

Возможно ли, что товары вашей корзины сохраняются сначала, а затем тележка? поэтому у дочерних элементов нет родительского идентификатора?

Вам необходимо явно сохранить корзину обратно в базу данных при создании, затем добавить элементы в нее и сохранить - только для получения идентификатора.

2

Почему вы включили .Cascade.SaveUpdate() в линии

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

?

Возможно, это смущает NHibernate (или Fluent NHibernate), что, кажется, каскадные сбережения/обновления с обоих концов вашего отношения?

Настройка вашего HasMany на каскад должна быть достаточной для достижения желаемого.

3

У меня была эта точная проблема с плавным nhibernate. Кажется, существует небольшая ошибка при сопоставлении отношений «один ко многим», а отношения не сохраняются автоматически или каскадируются. See here for a posting about it on the Fluent NHibernate group.

Видимо, есть кто-то, кто работает над проблемой!

Я не могу сказать, что это проблема с вашим кодом, но it looks very similar to a problem I had. Надеюсь, что это помогает!

-4

Проблема заключается в вашей инструкции конфигурации sessionfactory. Не используйте Exposeconfiguration, если вы хотите, чтобы ваши данные сохранялись. Это наверняка решит вашу проблему сохранения данных.

+0

следует использовать схему schemaexport тщательно. – 2009-03-14 12:47:22

0

Как вы заметили, вы определили поля (в схеме базы данных) с идентификатором, поэтому эти поля должны быть установлены в файле карты. Пример как:

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

ошибка вы получаете, потому что вы не установили поля Идентичность в отображении, чтобы быть сгенерированы Identity, таким образом, когда вы пытаетесь сэкономить(), тождественность столбец не сгенерирован (и не установлен в базе данных), то он дает вам ошибку.

Смежные вопросы