Pregunta

Tengo dos clases A y B con una relación de muchos a uno de A a B (objetos múltiples A pueden hacer referencia al mismo B). La pregunta es, si la norma de supresión en el lado A es Cascade, Will B suprimirse únicamente cuando se elimina el última hace referencia a una o va a ser eliminado en el primero vez que una se elimina una asociada. La regla de eliminación para el lado B de la relación es Nulidad si lo que importa.

Además, he leído en los documentos de la base de datos que los asuntos bandera opcionales en algunos casos. Pero no estaba claro cómo las relaciones que ilustraban relacionado con mi caso. Estaban hablando de un caso de contención (B es propiedad de A), mientras que mi caso es una de suscripción / asociación (B está relacionado con A).

Podría simplemente gestionar eliminación programmaticaly en el código, pero quería permitir que la base de datos para hacer lo correcto, si es posible. Pero no está claro que la semántica de recolección de basura que estoy buscando son compatibles con Core Data.

¿Alguna sugerencia?

¿Fue útil?

Solución

Yo tenía el mismo objetivo que se tenía al parecer (eliminar B tan pronto como la última referencia es suprimido). Me tomó más tiempo de lo esperado para obtener este derecho. Sobre todo porque

  • En el momento se prepara para su eliminación, la relación-a-muchos en B podría no ser actualizado todavía, así que no se puede simplemente contar el referencia en B .
  • isDeleted en parece estar ya establecido durante -prepareForDeletion

Esto es lo que funcionó para mí si alguien está interesado (Voy a usar Departamento <- >> Employee porque es más fácil de leer):

Employee

- (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 . Yo 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 del almacén manual o importación de datos).

Otros consejos

Aquí hay un Swift 4 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)
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top