为什么我的NHibernate手提袋系列没有动态设置孩子的"父母ID"?
我有一个新对象,其中包含一些作为IList的属性的新对象。我通过sql profiler看到两个正在执行的插入查询..一个用于父级,具有新的guid id,一个用于子级,但是,引用父级的子级上的外键是一个空的guid。这是我对父母的映射:
<id name="BackerId"> <generator class="guid" /> </id> <property name="Name" /> <property name="PostCardSizeId" /> <property name="ItemNumber" /> <bag name="BackerEntries" table="BackerEntry" cascade="all" lazy="false" order-by="Priority"> <key column="BackerId" /> <one-to-many class="BackerEntry" /> </bag>
在Backer.cs类上,我将BackerEntries属性定义为
IList<BackerEntry>
当我尝试保存或者更新传入的实体时,在sql profiler中得到以下结果:
exec sp_executesql N'INSERT INTO Backer(Name,PostCardSizeId,ItemNumber,BackerId)值(@ p0,@ p1,@ p2,@ p3)',N'@ p0 nvarchar(3),@ p1 uniqueidentifier,@ p2 nvarchar(3 ),@ p3
uniqueidentifier',@ p0 = N'qaa',@ p1 ='BC95E7EB-5EE8-44B2-82FF30F5176684D',@ p2 = N'qaa',@ p3 ='18FBF8CE-FD22-4D08-A3B1-63D6DFF426E5'
exec sp_executesql N'INSERT INTO BackerEntry(BackerId,BackerEntryTypeId,名称,描述,MaxLength,IsRequired,优先级,BackerEntryId)值(@ p0,@ p1,@ p2,@ p3,@ p4,@ p5,@ p6,@ p7) ',N'@ p0 uniqueidentifier,@ p1 uniqueidentifier,@ p2 nvarchar(5),@ p3 nvarchar(5),@ p4 int,@ p5位,@ p6 int,@ p7 uniqueidentifier',@ p0 ='00000000-0000 -0000-0000-000000000000',@ p1 ='2C5BDD33-5DD3-42EC-AA0E-F1E548A5F6E4',@ p2 = N'qaadf',@ p3 = N'wasdf',@ p4 = 0,@ p5 = 1,@ p6 = 0,@ p7 ='FE9C4A35-6211-4E17-A75A-60CCB526F1CA'
如我们所见,它没有将子级BackerId的空GUID重置为父级的新真实GUID。
最后,异常抛出是:
"NHibernate.Exceptions.GenericADOException: could not insert: [CB.ThePostcardCompany.MiddleTier.BackerEntry][SQL: INSERT INTO BackerEntry (BackerId, BackerEntryTypeId, Name, Description, MaxLength, IsRequired, Priority, BackerEntryId) VALUES (?, ?, ?, ?, ?, ?, ?, ?)] ---\u003e System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint
编辑:解决了!下面的第一个答案为我指明了正确的方向。我需要在子映射和类上添加该反向引用。这允许它以纯.net的方式工作,但是,当接受json时,存在断开连接,因此我不得不想出一些古怪的代码来"重新添加"孩子。
解决方案
我们可能需要在映射类中添加NOT-NULL =" true":
<bag name="BackerEntries" table="BackerEntry" cascade="all" lazy="false" order-by="Priority"> <key column="BackerId" not-null="true"/> <one-to-many class="BackerEntry" /> </bag>
并确保我们具有为子类定义的映射的逆向:
<many-to-one name="parent" column="PARENT_ID" not-null="true"/>
在我当前的具有亲子关系的项目中,我与冬眠有类似的问题,这是解决方案的一部分。
我遇到了这个问题,我花了很长时间才弄清楚。
子表必须在其父外键上允许为空。
NHibernate喜欢将带有NULL的子代保存在外键列中,然后返回并使用正确的ParentId更新。