2011-08-19 14 views
10

Estoy intentando guardar (insertar) una entidad principal con una lista de entidades secundarias. Ambas entidades usan un Guid como claves principales. Las claves no admiten nulos y no hay ninguna relación clave establecida en el archivo db.Inserción de elementos primarios y secundarios con NHibernate al mismo tiempo

El guardado no funciona, se lanza una excepción que indica que estoy tratando de guardar un nulo en la clave externa principal en la tabla secundaria.

Estaba esperando que nhibernate cree una clave para el padre y permita que sus objetos secundarios lo conozcan. ¿Es esto una limitación de NHibernate o de utilizar Guids como claves principales?

Este answer sugiere que tenga que configurar el padre de manera manual, ¿es esta la única manera?

Éstos son mis asignaciones como referencia: mapeo

Padres:

HasMany(x => x.Children).KeyColumn("ParentKey").Inverse().Cascade.All(); 

mapeo Niño:

References(x => x.Parent).Not.Nullable().Column("ParentKey"); 

Respuesta

15

NHibernate no es magia. Es solo un ORM, si sus hijos no tienen su conjunto de referencia para el padre, ¿por qué supondría que debido a que el padre tiene una lista de hijos que la referencia de los niños, a su vez, DEBERÍA ser una referencia para el padre?

Creo que respondió su propia pregunta cuando indicó que las entidades Child no tienen su propiedad Parent (lo que significa que es nula, lo que significa que NHibernate intentará guardar un valor 'nulo' para la Identificación principal en su tabla de Niño).

Si utilizara estos objetos SIN NHibernate, tendría sentido que la referencia principal se establezca en las entidades secundarias cuando se agreguen.

EDIT: Esto es para el caso en el que haya especificado 'Inversa' en su asignación. Si se va a eliminar esta llamada a 'Inversa' que debería funcionar de la manera que quería que funcione como inverso estados que el otro extremo (la entidad secundaria) es responsable de hacer el seguimiento de la relación. Esto significa que necesita establecer manualmente la referencia del padre en el hijo.

Sin embargo, la eliminación de la declaración Inverso ocasionaría que el/los Hijo (s) se guardaran, el padre se guarde y luego el ID padre de los Hijos se ACTUALIZARÁ. Como tiene una restricción nula en el ID principal, esto significa que todavía no funcionará, ya que inicialmente insertaría el elemento secundario con un id principal de nulo.

Las dos soluciones serían ya sea a eliminar esta restricción, o simplemente para añadir un método a la entidad dominante llamada AddChild:

public void AddChild(Child childObj) 
{ 
    childObj.Parent = this; 
    Children.Add(childObj); 
} 

Añadir otro método llamado removeChild:

public void RemoveChild(Child childObj) 
{ 
    if (Children.Contains(childObj)) 
    { 
     Child.Parent = null; 
     Children.Remove(childObj); 
    } 
} 

Luego, solo use esos métodos para agregar/eliminar niños.

+1

Claro que no espero que la referencia esté allí en tiempo de ejecución antes de guardar (tal vez mi pregunta es engañosa, lo edito) - Lo que espero es que Nhibernate sepa que Parent y Children son nuevos, y saber cómo persistirlos con las llaves adecuadas ... ¿demasiado para preguntar? – Dan

+0

@Dan He actualizado mi respuesta para ser más útil. – docmanhattan

+0

solo para explicar más sobre las asignaciones y restringir consultar este enlace http://wiki.fluentnhibernate.org/Fluent_mapping#Access_strategies – cpoDesign

Cuestiones relacionadas