Trong một mối quan hệ nhiều-nhiều một chiều giữa Registration
và Item
, nơi một Registration
có ISet<Item> ItemsPurchased
và Item
không có tài liệu tham khảo lại để đăng ký (nó không phải là một cách hữu ích để khám phá những đồ vật), khi Tôi nhìn vào SQL được tạo ra, tôi thấythành thạo NHibernate - không cần thiết cập nhật
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
Các tham số được truyền cho bản cập nhật là chính xác, nhưng không có gì về mục đã thay đổi, vì vậy không cần cập nhật.
Lập bản đồ bằng cách tự động ghi đè này tại chỗ cho Registration
và không ghi đè cho Item
. Lược đồ DB trông hoàn toàn chính xác. Tôi đã xóa tất cả các quy ước và thử nghiệm lại và hành vi vẫn tiếp tục tồn tại, vì vậy nó không phải là bất kỳ quy ước lập bản đồ nào của tôi đang thực hiện điều này.
mapping.HasManyToMany(e => e.ItemsPurchased).AsSet().Cascade.All().Not.Inverse();
Tại sao NHibernate làm UPDATE
cuộc gọi này và những gì tôi có thể làm gì để ngăn chặn nó? Nó không thực sự làm tổn thương bất cứ điều gì nhưng nó cho thấy rằng tôi đã làm điều gì đó sai, vì vậy tôi muốn tìm ra những gì.
Edit: mỗi bình luận dưới đây, tôi đã tạo ra một thử nghiệm đơn vị mà tạo ra một Event
(Item
phải thuộc về một Event
), thêm hai Items
với nó, evicts là người đầu tiên từ phiên và xóa phiên, sau đó Gets là người đầu tiên trở lại bằng ID của nó.
tôi nhận thấy một cái gì đó kỳ lạ trong dòng sản phẩm Chọn danh sách bên (thứ 2 từ dưới)
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)]
Bảng này được tạo ra một cách chính xác:
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)
)
Các DateTimes là cố tình nullable vì một mục có thể không cần để có ngày cụ thể (ví dụ về thứ gì đó sẽ là "đăng ký sớm chim").
Để xác nhận vấn đề cập nhật ảo, 'Nhận' cùng một mục và kiểm tra xem bản cập nhật có được phát hành khi bật/cam kết hay không. Sau đó, bạn có thể loại trừ bất kỳ vấn đề xếp tầng nhiều đến nhiều. – dotjoe
Điều này có liên quan đến việc có một trường thập phân không? Google sẽ đưa ra một số kết quả cho Bản cập nhật và số thập phân của Phantom, nhưng tôi chưa nhận được phần cuối của những gì họ nói. –