nhibernate fluent-nhibernate nhibernate-mapping

fluent nhibernate mapping



NHibernate: Usando Fluent Nhibernate para salvar objetos infantiles (8)

¿Es posible que sus artículos de carrito estén guardando primero, luego el carrito? por lo tanto, los elementos secundarios no tienen ID de padre para usar?

PUEDE tener que guardar de forma explícita el carrito de vuelta en el DB en la creación, luego agregar los artículos en él y guardarlo, solo para obtener el ID.

En mi sistema, tengo dos entidades: ShoppingCart y ShoppingCartItem. Un caso de uso bastante genérico. Sin embargo, cuando guardo mi ShoppingCart, ninguno de los elementos se guarda en la base de datos.

Dentro de mi objeto, creo un nuevo objeto ShoppingCart.

ShoppingCart cart = CreateOrGetCart();

Luego agrego un producto existente que obtuve de la base de datos al comienzo.

cart.AddItem(product);

Esto es solo un simple contenedor para agregar el artículo al IList.

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

Luego llamo a SaveOrUpdate en el Repositorio

Repository.SaveOrUpdate(cart);

Que se ve así:

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

Estoy usando Fluent NHibernate para el mapeo:

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(); }

El esquema de base de datos (SQL Server 2005) también es bastante genérico:

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

Cuando guardoOctualice mi ShoppingCart, ¿por qué no se guarda ningún ShoppingCartItems?

Por favor ayuda.

Gracias

Ben

ACTUALIZACIÓN: Envolverlo en una transacción que me proporciona más información:

No se puede insertar el valor NULL en la columna ''ShoppingCartId'', tabla ''WroxPizza.dbo.ShoppingCartItems''; la columna no permite nulos. INSERT falla La instrucción se ha terminado.

Esto se debe a que es un carrito nuevo.


Intente envolver Session.SaveOrUpdate en una transacción, o fuerce una descarga directamente después.


No estoy seguro, pero no creo que NHibernate conecte el ahorro de objetos a objetos secundarios. No muestra el código que llama a SaveOrUpdate, pero sé que si recorre ShoppingCartItems en ese momento, guardando cada uno individualmente, también se mantendrán.


No sé nada sobre NHibernate (El OPF que uso lo hace por mí), pero ¿no es cierto que al guardar la raíz agregada (ShoppingCart), ese código también debe enviar sus instancias compuestas a la sesión también?


¿Por qué .Cascade.SaveUpdate() en la línea?

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

?

Quizás confunde NHibernate (o Fluiber NHibernate) que parece haber actualizaciones / actualizaciones en cascada desde ambos extremos de su relación.

La configuración de HasMany en cascada debería ser suficiente para lograr lo que desea.



Como se notó, usted definió (en el esquema de la base de datos) los campos con Identidad, por lo tanto, estos campos se deben establecer en el archivo de Mapa. Ejemplo como el siguiente:

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

el error que está recibiendo porque no estableció los campos de Identidad en la asignación generada por Identity, por lo tanto, cuando está intentando Guardar (), la columna Identidad no se genera (y se establece como no nula en la base de datos) entonces te da el error.


El problema es con su declaración de configuración de sessionfactory. No use Exposeconfiguration si desea que sus datos persistan. Eso seguramente resolverá su problema de persistencia de datos.