En una relación unidireccional muchos-a-muchos entre Registration
y Item
, donde un Registration
tiene un ISet<Item> ItemsPurchased
y Item
tiene ninguna referencia de nuevo a registros (que no es una forma útil para explorar el gráfico de objetos), cuando miro el SQL que se genera, veoFluido NHibernate - actualización innecesaria
INSERT INTO Registrations_Items (RegistrationId, ItemId) VALUES (@p0, @p1);@p0 = 1 [Type: Int32 (0)], @p1 = 1 [Type: Int32 (0)]
UPDATE Items SET Price = @p0, Name = @p1, [...], ListIndex = @p5, EventId = @p6 WHERE ItemId = @p7
los parámetros pasados a la actualización son correctas, pero nada sobre el artículo ha cambiado, por lo que no es necesaria la actualización.
El mapeo se realiza automatizando con esta anulación en lugar de Registration
y sin anulaciones para Item
. DB Schema parece completamente correcto. Eliminé todas las convenciones y probé de nuevo y el comportamiento persistió, por lo que no es una de mis convenciones de mapeo lo que hace esto.
mapping.HasManyToMany(e => e.ItemsPurchased).AsSet().Cascade.All().Not.Inverse();
¿Por qué es NHibernate haciendo este UPDATE
llamada y qué se puede hacer para detenerlo? Realmente no está lastimando nada, pero sugiere que hice algo mal, así que me gustaría descubrir qué.
Editar: Per comentario a continuación, he creado una prueba de unidad que crea un Event
(Item
deben pertenecer a una Event
), añade dos Items
a ella, desaloja el primero de la sesión y elimina la sesión, a continuación, obtiene el primer de vuelta por su ID.
noto algo extraño en la línea de artículos Seleccione abajo (segunda desde la parte inferior)
INSERT INTO Events (blah blah blah...)
select @@IDENTITY
INSERT INTO Items (Price, Name, StartDate, EndDate, ExternalID, ListIndex, EventId) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6);@p0 = 100.42 [Type: Decimal (0)], @p1 = 'Item 1' [Type: String (0)], @p2 = NULL [Type: DateTime (0)], @p3 = NULL [Type: DateTime (0)], @p4 = '123' [Type: String (0)], @p5 = 0 [Type: Int32 (0)], @p6 = 1 [Type: Int32 (0)]
select @@IDENTITY
SELECT blah blah blah FROM Events event0_ WHERE [email protected];@p0 = 1 [Type: Int32 (0)]
SELECT itemsforsa0_.EventId as EventId1_, itemsforsa0_.ItemId as ItemId1_, itemsforsa0_.ListIndex as ListIndex1_, itemsforsa0_.ItemId as ItemId3_0_, itemsforsa0_.Price as Price3_0_, itemsforsa0_.Name as Name3_0_, itemsforsa0_.StartDate as StartDate3_0_, itemsforsa0_.EndDate as EndDate3_0_, itemsforsa0_.ExternalID as ExternalID3_0_, itemsforsa0_.ListIndex as ListIndex3_0_, itemsforsa0_.EventId as EventId3_0_ FROM Items itemsforsa0_ WHERE [email protected];@p0 = 1 [Type: Int32 (0)]
UPDATE Items SET Price = @p0, Name = @p1, StartDate = @p2, EndDate = @p3, ExternalID = @p4, ListIndex = @p5, EventId = @p6 WHERE ItemId = @p7;@p0 = 100.42000 [Type: Decimal (0)], @p1 = 'Item 1' [Type: String (0)], @p2 = NULL [Type: DateTime (0)], @p3 = NULL [Type: DateTime (0)], @p4 = '123' [Type: String (0)], @p5 = 0 [Type: Int32 (0)], @p6 = 1 [Type: Int32 (0)], @p7 = 1 [Type: Int32 (0)]
La tabla se crea correctamente:
create table Items (
ItemId INT IDENTITY NOT NULL,
Price NUMERIC(19,5) not null,
Name NVARCHAR(255) not null,
StartDate DATETIME null,
EndDate DATETIME null,
ExternalID NVARCHAR(255) not null,
ListIndex INT not null,
EventId INT not null,
primary key (ItemId)
)
Los DateTime son deliberadamente anulable porque un objeto que puede ser que necesite ser específico de la fecha (un ejemplo de algo sería el "registro anticipado").
Para confirmar un problema de actualización fantasma, 'Obtenga' ese mismo elemento y compruebe si se ha emitido una actualización sobre flush/commit. Entonces puede descartar cualquier problema de cascada de muchos a muchos. – dotjoe
¿Podría esto estar relacionado con tener un campo decimal? Google muestra algunos resultados para las Actualizaciones Phantom y el decimal, pero todavía no he llegado al final de lo que dicen. –