In einer unidirektionalen many-to-many-Beziehung zwischen Registration
und Item
, wo ein Registration
hat eine ISet<Item> ItemsPurchased
und Item
keinen Rückbezug auf Registrierungen haben (es ist kein brauchbarer Weg, um die Objektgraphen zu erkunden), wenn ich schaue auf die SQL erzeugt wird, sehe ichFluent NHibernate - Unnötige Update
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
die Parameter für das Update vergangen sind korrekt, aber nichts über den Punkt hat sich geändert, so dass das Update nicht erforderlich ist.
Die Zuordnung erfolgt durch automatisches Überschreiben mit dieser Überschreibung anstelle von Registration
und keine Überschreibungen für Item
. DB-Schema sieht vollständig korrekt aus. Ich entfernte alle Konventionen und testete erneut und das Verhalten blieb bestehen, so dass es keine meiner Zuordnungskonventionen ist, die dies tun.
mapping.HasManyToMany(e => e.ItemsPurchased).AsSet().Cascade.All().Not.Inverse();
Warum macht NHibernate diese UPDATE
Anruf und was kann ich tun, um es zu stoppen? Es tut nicht wirklich weh, aber es deutet darauf hin, dass ich etwas falsch gemacht habe, also würde ich gerne herausfinden, was.
Edit: Per Kommentar unten, habe ich einen Komponententest, der ein Event
erzeugt (Item
zu einem Event
gehören müssen), fügt zwei Items
es, die erste von Sitzung evicts und Sitzungs spült, dann erhält der erste zurück durch seine ID.
Ich bemerke etwas Merkwürdiges in der Zeile SELECT Elemente unten (2. von unten)
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)]
Die Tabelle korrekt erstellt:
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)
)
Die Datetime sind bewusst auf NULL festlegbare, weil ein Artikel nicht benötigen datumsspezifisch sein (ein Beispiel für etwas, das "Frühbucherregistrierung" wäre).
Um ein Phantom-Update-Problem zu bestätigen, "Get" das gleiche Element und prüfen, ob eine Aktualisierung auf Flush/Commit ausgegeben wird. Dann können Sie jedes kaskadierende Problem von vielen zu vielen ausschließen. – dotjoe
Könnte dies mit einem Dezimalfeld zusammenhängen? Google zeigt einige Ergebnisse für Phantom Updates und Dezimalzahlen an, aber ich bin noch nicht auf den Grund gekommen, was sie alle sagen. –