Почему моя коллекция сумок NHibernate не устанавливает «родительский идентификатор» детей динамически?

StackOverflow https://stackoverflow.com/questions/146604

Вопрос

У меня есть новый объект с набором новых объектов внутри него по какому-то свойству в виде IList.Я вижу через профилировщик sql, что выполняются два запроса на вставку.один для родителя, который имеет новый идентификатор guid, и один для дочернего элемента, однако внешний ключ дочернего элемента, который ссылается на родителя, является пустым 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>

Когда я пытаюсь SaveOrUpdate переданный объект, я получаю следующие результаты в профилировщике sql:

exec sp_executesql n'insert в Backer (name, postcardsizeid, itemnumber, backerid) значения (@p0,@p1,@p2,@p3) ', n'@p0 nvarchar (3),@p1 уникальный определение,@p2 nvarchar (3 ),@p3 uniquidentifier ',@p0 = n'qaa',@p1 = 'bc95eb-5ee8-44b2-82ff30f5176684d',@p2 = n'qaa ',@p3 =' 18fbf8ce-fd22-4d08-a3b1-63d6dff426e56c8ce-fd22-4d08-a3b1-63d6dff426e56c8ce-fd22-4d08-a3b1-63d6df426e5 a

exec sp_executesql N'INSERT INTO BackerEntry (BackerId, BackerEntryTypeId, Name, Описание, MaxLength, IsRequired, Priority, BackerEntryId) ЗНАЧЕНИЯ (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7) ',N'@p0 уникальный идентификатор, @p1 уникальный идентификатор, @p2 nvarchar(5), @p3 nvarchar(5), @p4 int, @p5 бит, @p6 int, @p7 уникальный идентификатор',@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 дочернего элемента не сбрасывается на новый реальный идентификатор родительского элемента.

Наконец, исключение:

"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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top