5

Tengo una relación muchos a muchos:¿Cómo eliminar en una relación de muchos a muchos?

El producto tiene muchas categorías y la categoría tiene muchos productos.

Decir que tengo

Shopping Category 
Food Category 

Product A - Shopping Category, Food Category 
Product B - Shopping Category 

Ahora borro Shopping Category. Quiero que la referencia Product A se elimine de Shopping Category y deseo que Product B se elimine por completo.

que iba a terminar con:

Product A - Food Category. 

¿Cómo se hace esto en nhibernate (estoy usando NHibernate fluidez).

Traté de usar Cascade DeleteOrphan y AllDeleteOrphan pero cuando lo hago y elimino Shopping, tanto el Producto A como el B se eliminan.

public class CategoryMapping : ClassMap<Category> 
{ 
    public CategoryMapping() 
    { 
     Id(x => x.Id).GeneratedBy.GuidComb(); 

     Map(x => x.Name).Not.Nullable().NvarcharWithMaxSize(); 
     HasManyToMany(x => x.Products).Cascade.DeleteOrphan(); 
    } 
} 


public class ProductMapping : ClassMap<Product> 
{ 
    public ProductMapping() 
    { 
     Id(x => x.Id).GeneratedBy.GuidComb(); 
     Map(x => x.Name).Not.Nullable().NvarcharWithMaxSize(); 
     HasManyToMany(x => x.Categories); 
    } 
} 

    unitOfWork.BeginTransaction(); 
    Category category =session.Load<Category>(id); 
    session.Delete(category); 
    unitOfWork.Commit(); 

Respuesta

2

No creo que esto se pueda manejar mapeando con la estructura de datos existente. Creo que necesitarías escribir un código manual (*) o cambiar la estructura de datos.

(*) No es 100% seguro de que funciona, aunque ...

unitOfWork.BeginTransaction(); 
Category category =session.Load<Category>(id); 
var productsDel = category.Products.Where(p => p.Categories.Count == 1); 
productsDel.ForEach(p => session.Delete(p)); 
session.Delete(category); 
unitOfWork.Commit(); 

Otros:

También estoy pensando en añadir la cartografía para las tablas de referencia cruzada. Entonces debería poder configurar el mapeo para que elimine solo los registros de esa tabla de referencias cruzadas. Deberá verificar si hay productos sin referencias y eliminarlos periódicamente. (algunos códigos de limpieza periódicos, como ejecutar algún procedimiento almacenado). Sé que esta solución huele mal :) Todavía hay desencadenantes y otras cosas de SQL Server ... no son soluciones buenas de todos modos, sino soluciones.

0

Si lo que desea es eliminar la asociación entre los dos utilización Cascade.SaveUpdate()

A continuación, basta con retirar la entidad de la colección y confirmar la transacción si está utilizando transacciones si no se tendrá que hacer una sesión .Flush

+0

No entiendo. Pensé que saveUpdate lo guardaría y no estoy seguro de a qué se refiere con eliminar la entidad de la colección. Podría tener miles de productos que necesitan que se eliminen sus referencias cuando elimine la catergoría, así que esto parece ser lo que sería una cascada para que yo tenga que hacerlo. – chobo2

+0

Puede que haya entendido mal su pregunta, pero definitivamente puedo ver por qué 'DeleteOrphan' y' AllDeleteOrphan' eliminan el Producto A en esta instancia. 'SaveUpdate' solo eliminará las asociaciones (las muchas a muchas entradas de la tabla ...' product_category') pero no eliminará 'Product A'. Esto es algo que tendría que manejar manualmente al usar esta configuración de cascada. No creo que haya una cascada que maneje esto (aunque podría estar equivocado). –

+0

Hmm tendré que intentarlo, pero pensé que DeleteOrphan era exactamente para esta situación. No lo veo como para mí. El Producto A no es huérfano ya que todavía tiene una relación con algo. – chobo2

Cuestiones relacionadas