【发布时间】:2012-06-05 03:08:47
【问题描述】:
在Registration 和Item 之间的单向多对多关系中,Registration 有一个ISet<Item> ItemsPurchased,而Item 没有引用回注册(这不是探索对象图),当我查看正在生成的 SQL 时,我看到了
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
传递给更新的参数是正确的,但是Item没有任何变化,所以不需要更新。
映射是通过自动映射 Registration 的覆盖,而 Item 没有覆盖。 DB Schema 看起来完全正确。我删除了所有约定并再次测试,并且行为仍然存在,因此不是我的任何映射约定都在这样做。
mapping.HasManyToMany(e => e.ItemsPurchased).AsSet().Cascade.All().Not.Inverse();
为什么 NHibernate 会发出这个 UPDATE 电话,我该怎么做才能阻止它?这并没有真正伤害任何东西,但它表明我做错了什么,所以我想弄清楚是什么。
编辑:
根据下面的评论,我创建了一个单元测试,它创建了一个Event(Item 必须属于一个Event),向其中添加两个Items,从会话中驱逐第一个并刷新会话,然后获取第一个返回通过它的 ID。
我注意到下面的 SELECT 项目行中有一些奇怪的地方(倒数第二个)
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 event0_.EventId=@p0;@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 itemsforsa0_.EventId=@p0;@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)]
表创建正确:
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)
)
DateTimes 故意可以为空,因为项目可能不需要特定日期(例如“早鸟注册”)。
【问题讨论】:
-
要确认幻影更新问题,
Get同一项目并检查是否在刷新/提交时发布了更新。然后您可以排除任何多对多级联问题。 -
这可能与有一个小数字段有关吗? Google 为 Phantom Updates 和 decimal 提供了一些结果,但我还没有深入了解他们所说的内容。
标签: nhibernate fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping