77 votos

Cómo eliminar niño objeto en NHibernate?

Tengo un objeto principal que se tiene una relación de uno a varios con una interfaz IList de los objetos secundarios. ¿Cuál es la mejor manera de eliminar los objetos secundarios? Yo no soy eliminación de los padres. Mi objeto principal contiene una interfaz IList de los objetos secundarios. Aquí es el mapeo de la relación de uno a varios:

<bag name="Tiers" cascade="all">
  <key column="mismatch_id_no" />
  <one-to-many class="TGR_BL.PromoTier,TGR_BL"/>
</bag>

Si trato de quitar todos los objetos de la colección utilizando clear(), a continuación, llamar SaveOrUpdate(), me sale esta excepción:

System.Data.SqlClient.SqlException: Cannot insert the value NULL into column

Si trato de borrar al niño objetos de forma individual, a continuación, eliminarlas de la de los padres, puedo obtener una excepción:

deleted object would be re-saved by cascade

Esta es mi primera vez tratando con la eliminación de los objetos secundarios en Fluent. ¿Qué estoy haciendo mal?

edit: Solo para aclarar - NO estoy tratando de eliminar el objeto primario, sólo los objetos secundarios. Tengo la relación establecida como un uno a muchos padres. ¿Necesito crear una relación de equivalencia en el objeto secundario de asignación?

134voto

Chuck Puntos 6314

Usted está recibiendo el primer error, ya que, al eliminar los elementos de la colección, NHibernate modo de funcionamiento predeterminado es simplemente romper la asociación. En la base de datos, NHibernate intenta establecer la columna de clave externa en la fila a null. Ya que no permiten valores null en la columna, SQL Server genera el error. Borrar el la colección no necesariamente eliminar el objeto secundario, pero una manera de hacerlo es establecer cascade=all-delete-orphan. Este le informa de NHibernate que se debe eliminar a los que quedan huérfanos de filas en lugar de la configuración de la columna de clave externa.

Usted está obteniendo el segundo error, porque cuando llame SaveOrUpdate NHibernate primero elimina a todos los objetos secundarios. Luego, porque ni la relación está marcada como inversa, Fluent también intenta establecer la columna de clave externa en la tabla secundaria a null. Desde las filas ya se han eliminado, recibirá el segundo error. Usted necesita establecer inversa=true en uno de los lados de su relación para solucionar este problema. Esto se hace generalmente en la uno (clave primaria o principal) de lado. Si no haces esto, NHibernate hará que las actualizaciones adecuadas para cada lado de la relación. Por desgracia, la ejecución de dos actualizaciones no es el apropiado.

Siempre debe marcar uno de los lados de sus relaciones como la inversa de lado. Dependiendo de cómo el código, que puede o no puede necesitar el uso de cascada. Si usted desea tomar ventaja de un disparo elimina como usted está tratando de hacer mediante Clear(), se necesita definir la cascada.

3voto

hanuman0503 Puntos 138

De acuerdo a Chuck respuesta, he resuelto mi problema mediante la adición de Inverse = true en el padre por el lado de asignación:

Mensaje tiene muchos MessageSentTo:

[HasMany(typeof(MessageSentTo), Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Inverse = true)]
public IList<MessageSentTo> MessageSendTos
{
    get { return m_MessageSendTo; }
    set { m_MessageSendTo = value; }
}

Yo estoy usando el Castillo de ActiveRecord. Gracias Chuck.

2voto

Liath Puntos 3759

En nuestro ejemplo tenemos categorías con muchos productos si un producto no acepta valores null.

Usted puede solucionar el problema mediante la eliminación del producto y la eliminación de los padres de la colección antes de la descarga, pero estamos todavía en busca de una mejor solución para esto.

product = pRepo.GetByID(newProduct.ProductID);
product.Category.Products.Remove(product);
pRepo.Delete(product);

Espero ayuda de todos modos

2voto

Elie Puntos 7628

Trate de usar merge() en lugar de saveOrUpdate(). También, asegúrese de que su cascada se establece en all-delete-orphan y que su relación padre-hijo es invertible (inverse=true en caso de que el padre y, a continuación, un campo en el niño que es el padre-identificación con el no-null=true).

0voto

Thomas Tekavec Puntos 41

Cambio cascada de valor de atributo de "todos" a "all-delete-orphan".

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X