2010-12-10 7 views
6

que tengo x el que un objeto de tipo objectX que tiene una propiedad ListOfObjectYs eso es unEn nhibernate, no es capaz de lista de niño actualizar objetos

List<objectY> 

el mapeo nhibernate se ve así:

public ObjectXMap() 
    { 
     HasMany(x => x.ListOfObjectYs).AsBag().Inverse(); 
    } 

cuando voy a guardarlo, puedo cambiar algunas propiedades de objectX y luego tener :

Session.SaveOrUpdate(x); 

ahora necesito actualizar esta propiedad que es una lista. Obtengo una nueva lista de objectYs y quiero reemplazar la lista existente de objectY con una nueva lista. ¿Necesito hacer esto?

foreach (ObjectY y in x.ListOfObjectYs) 
       { 
        Session.Delete(y); 
        deleted = true; 
       } 
       if (deleted) 
       { 
        _session.Flush(); 
       } 
       x.ListOfObjectYs.Clear(); 

       foreach (ObjectY y in newObjectYList) 
       { 
        x.ListOfObjectYs.Add(y); 
        Session.SaveOrUpdate(y); 
       } 
       _session.Flush(); 

mis preguntas son:

  1. ¿Tengo que borrar todo y al ras antes de añadir otros nuevos.
  2. ¿Necesito hacer todo esto incrementales guarda en el medio

hay una mejor manera de hacer esta actualización en las que necesito para actualizar un objeto (propiedades), sino también actualizar las propiedades que son lista donde hay una lista completamente nueva (lo que significa que los elementos deben ser eliminados y agregados).

Respuesta

3

Las respuestas a sus preguntas son no y no. Si desea reemplazar la lista, debe borrarla y agregar nuevos elementos. Si tiene configurado en cascada para eliminar por completo a huérfano, como en la respuesta de James Kovacs, los cambios en la colección se mantendrán cuando la sesión se vacíe.

Es importante entender lo que significan Guardar, Actualizar y saveOrUpdate en NHibernate:

  • Guardar - hacer un nuevo objeto persistente
  • Update - hacer un objeto separado cambiada persistente
  • saveOrUpdate - Guardar o Actualización según el valor no guardado del identificador del objeto

Véase también Manipulating Persistent Data.

Suponiendo que todos los objetos se cargaron en la misma sesión a continuación, la sustitución de una colección puede ser tan fácil como:

x.ListOfObjectYs.Clear(); 
foreach (ObjectY y in newObjectYList) 
{ 
    x.ListOfObjectYs.Add(y); 
} 
_session.Flush(); 
+0

¿cómo puedes hacer eso sin realmente guardar los objetos Y? es su punto, esa cascada.AllDeleteOrphan() se ocupa de eso ?? – leora

+0

ahora recibo un error: una colección con cascada = "todo-eliminar-huérfano" ya no era referenciada por la instancia de la entidad propietaria: ObjectY – leora

+3

Si los objetos Y son nuevos, primero debe guardarlos para hacerlos persistentes. El mensaje de error puede indicar que está reasignando la referencia de la colección en algún lugar, consulte http://www.sleberknight.com/blog/sleberkn/entry/20070329 y http://stackoverflow.com/questions/2127016/nhibernate-mapping -a-collection-with-cascadeall-delete-orphan-was-no-longer-r. –

3

Necesita una cascada en su HasMany(). Si los objetos secundarios son propiedad total del padre, Cascade.AllDeleteOrphan() es una buena opción. De esta forma, las copias guardadas, las actualizaciones y las eliminaciones en el elemento primario se conectan en cascada automáticamente a los objetos secundarios, lo que elimina la necesidad de su complejo bloque foreach. Con esto en su lugar, simplemente actualice su colección y comprometa su transacción. NHibernate se encargará del resto.

ACTUALIZACIÓN: para modificar la lista, simplemente agregue y elimine elementos de la lista como lo haría normalmente con una colección .NET. Por ejemplo:

public void RemoveY(ObjectY someY) { 
    ListOfObjectYs.Remove(someY); 
} 

public void AddY(ObjectY someY) { 
    ListOfObjectYs.Add(someY); 
} 

public void ClearAllY() { 
    ListOfObjectYs.Clear(); 
} 

Cuando se confirma la transacción, cualquier cambio en la colección ListOfObjectYs serán persistieron a lo largo con el padre ObjectX.

+0

Para que quede claro, añado Cascade.AllDeleteOrphan() a mi archivo de asignación. Eso es simplemente suficiente. ¿Puede proporcionar la sintaxis para hacer la actualización de la lista, ya que no entiendo exactamente lo que quiere decir, "puedo eliminar el para cada uno", en algún momento tengo que eliminar las entradas existentes y agregar nuevas. No veo cómo salgo de esto. – leora

+0

- ahora recibo un error: una colección con cascade = "all-delete-huérfano" ya no era referenciada por la instancia de la entidad propietaria: ObjectY – leora

+0

¿Está asignando una colección a otra? p.ej. x1.ListOfYs = x2.ListOfYs? Debería copiar elementos entre colecciones, sin duplicar referencias a colecciones. Si no es así, deberá proporcionar el código correspondiente. –

Cuestiones relacionadas