2010-02-04 10 views
20

Tengo dos clases A y B con una relación de varios a varios desde A hasta B (varios objetos A pueden hacer referencia al mismo B). La pregunta es, si la regla de eliminación en el lado A es Cascade, se eliminará B solo cuando se elimine última haciendo referencia a A o se eliminará el cuando se borra una asociada A. La regla de eliminación para el lado B de la relación es Anular si eso es importante.iPhone Core Data: eliminación en cascada en una relación de varios a uno

Además, leí en los documentos de Core Data que el indicador opcional importa en algunos casos. Pero no estaba claro cómo las relaciones que estaban ilustrando se relacionaban con mi caso. Hablaban de un caso de contención (B es propiedad de A) mientras que mi caso es de suscripción/asociación (B está relacionado con A).

Podría simplemente gestionar la eliminación de programas programáticamente en el código, pero quería permitir que Core Data hiciera lo correcto si fuera posible. Pero no está claro que la semántica de recolección de basura que estoy buscando sea compatible con Core Data.

¿Alguna sugerencia?

Respuesta

14

que tenían el mismo objetivo que se tenía al parecer (eliminar B tan pronto como la última referencia Un se elimina). Me tomó más tiempo de lo esperado para hacerlo bien. Sobre todo porque

  • En el momento Un prepara para su eliminación, la relación-a-muchos en B no podría actualizarse sin embargo, por lo que no se puede simplemente contar el Un referencia en B.
  • isDeleted en Un parece estar ya establecido durante -prepareForDeletion

Esto es lo que funcionó para mí si alguien está interesado (utilizaré Departamento < - >>Empleado porque es más fácil de leer):

En Empleado:

- (void)prepareForDeletion { 
    // Delete our department if we we're the last employee associated with it. 
    Department *department = self.department; 
    if (department && (department.isDeleted == NO)) { 
     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isDeleted == NO"]; 
     NSSet *employees = [department.employees filteredSetUsingPredicate:predicate]; 

     if ([employees count] == 0) {   
      [self.managedObjectContext deleteObject:department]; 
     } 
    } 
} 

Otras personas han sugerido poner esta lógica en -willSave en Departamento. Prefiero la solución anterior, ya que en realidad podría querer guardar un departamento vacío en algunos casos (por ejemplo, durante la migración manual de la tienda o la importación de datos).

+0

Sólo una sugerencia ... Puesto que los documentos no dicen que no es necesario mensaje estupendo, que es probablemente una buena idea hacer Entonces: [superpreparacionparaDelecion] –

0

Aquí está un Swift versión de respuesta de Lukas:

public override func prepareForDeletion() { 
    guard let department = department else { return } 

    if department.employees.filter({ !$0.isDeleted }).isEmpty { 
     managedObjectContext?.delete(department) 
    } 
} 
Cuestiones relacionadas