2008-09-28 20 views
8

Tengo un objeto nuevo con una colección de objetos nuevos dentro de él en algunas propiedades como IList. Veo a través de sql profiler dos consultas de inserción que se ejecutan .. una para el padre, que tiene la nueva ID de GUID, y otra para el hijo, sin embargo, la clave externa en el hijo que hace referencia al padre, es un GUID vacío. Aquí está mi mapeo de los padres:¿Por qué mi colección de bolsos NHibernate no establece dinámicamente la 'identificación principal' de los niños?

<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, he definido como la propiedad BackerEntries

IList<BackerEntry> 

Cuando intento saveOrUpdate la pasó en la entidad consigo los siguientes resultados en SQL profiler:

exec sp_executesql N'INSERT INTO Backer (Nombre, PostCardSizeId, ItemNumber, BackerId) VALORES (@ p0, @ p1, @ p2, @ p3) ', N' @ p0 nvarchar (3), @ p1 uniqueidentifier , @ p2 nvarchar (3), @ p3 uniqueidentifier ', @ p0 = N'qaa', @ p1 = 'BC95E7EB-5EE8-44B2-82FF3 0F5176684D '@ p2 = N'qaa', @ p3 = '18FBF8CE-FD22-4D08-A3B1-63D6DFF426E5'

sp_executesql

ejecutivo N'INSERT EN BackerEntry (BackerId, BackerEntryTypeId, nombre, descripción, MaxLength, isRequired, Prioridad , BackerEntryId) VALUES (@ p0, @ p1, @ p2, @ p3, @ p4, @ p5, @ p6, @ p7) ', N' @ p0 uniqueidentifier, @ p1 uniqueidentifier, @ 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 restablece el guid vacío para BackerId en el elemento secundario al nuevo guid real del elemento primario.

Por último, el lanzamiento 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 

EDIT: SOLUCIONADO! La primera respuesta a continuación me indicó la dirección correcta. Necesitaba agregar esa referencia en el mapeo y la clase del niño. Esto permitió que funcionara de una manera puramente. Sin embargo, al aceptar json, hubo una desconexión, así que tuve que encontrar un código peculiar para "volver a conectar" a los niños.

Respuesta

9

Es posible que tenga que añadir NO-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> 

, así como asegurarse de que tiene el reverso de la asignación definida para la clase hija:

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

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

+0

Gracias ... Me apuntó en la dirección correcta ... No tenía la referencia anterior en el mapeo de mi hijo. – EvilSyn

0

Tuve este problema y me llevó mucho tiempo darme cuenta. La tabla secundaria debe permitir nulos en su clave externa principal. NHibernate le gusta guardar los elementos secundarios con NULL en la columna de clave externa y luego volver y actualizar con el ParentId correcto.

+1

¿Es esto cierto? – Dan

+1

Definitivamente no es cierto, debe asignar una asociación bidireccional de modo que el extremo inverso sea el padre y establecer las propiedades en ambos lados. http://www.nhforge.org/doc/nh/en/index.html#collections-bidirectional – dotjoe

+0

+1. Sí, es cierto. La columna FK en la tabla secundaria tiene que ser anulable para que esto funcione.NHibernate agrega el elemento secundario con ParentID a NULL y luego actualiza ParentID cuando Parent se guarda en la base de datos. –

Cuestiones relacionadas