¿Por qué mi colección de bolsas NHibernate no configura dinámicamente la 'identificación de los padres' de los niños?

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

Pregunta

Tengo un nuevo objeto con una colección de nuevos objetos dentro de él en alguna propiedad como un IList. Veo a través del perfil de SQL que se están ejecutando dos consultas de inserción ... una para el padre, que tiene el nuevo ID de guía, y otra para el hijo, sin embargo, la clave foránea en el hijo que hace referencia al padre, es una guía vacía. Aquí está mi asignación en el padre:

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

En la clase Backer.cs, definí la propiedad BackerEntries como

IList<BackerEntry>

Cuando intento guardar o actualizar la entidad pasada, obtengo los siguientes resultados en el perfilador de SQL:

exec sp_executesql N'INSERT INTO Backer (Name, PostCardSizeId, ItemNumber, BackerId) VALUES (@ p0, @ p1, @ p2, @ p3) ', N' @ p0 nvarchar (3), @ p1 identificador único, @ p2 nvarchar (3), @ p3 identificador único ', @ 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, Name, Description, MaxLength, IsRequired, Priority, BackerEntryId) VALUES (@ p0, @ p1, @ p2, @ p3, @ p4, @ p5, @ p6, @ p7) ', N' @ p0 identificador único, @ p1 identificador único, @ p2 nvarchar (5), @ p3 nvarchar (5), @ p4 int, @ p5 bit, @ 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'

Como puede ver, no se restablece el guid vacío para BackerId en el hijo al nuevo guid real del padre.

Finalmente, el lanzamiento de excepción es:

"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

EDITAR: ¡RESUELTO! La primera respuesta a continuación me indicó la dirección correcta. Necesitaba agregar esa referencia en la asignación y clase del niño. Esto permitió que funcionara de una manera puramente .net; sin embargo, al aceptar a json, hubo una desconexión, así que tuve que idear un código peculiar para "volver a adjuntar" a los niños.

¿Fue útil?

Solución

Es posible que debas agregar NOT-NULL = " true " a su clase de mapeo:

<bag name="BackerEntries" table="BackerEntry" cascade="all" lazy="false" order-by="Priority">
  <key column="BackerId" not-null="true"/>
  <one-to-many class="BackerEntry" />
</bag>

y asegúrese de que tiene el reverso de la asignación definida para la clase secundaria:

<many-to-one name="parent" column="PARENT_ID" not-null="true"/>

Tuve problemas similares con la hibernación en mi proyecto actual con relaciones entre padres e hijos, y esto era parte de la solución.

Otros consejos

Tuve este problema y me tomó una eternidad entenderlo. La tabla secundaria debe permitir nulos en su clave externa principal. A NHibernate le gusta guardar a los niños con NULL en la columna de clave externa y luego regresar y actualizar con el ParentId correcto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top