2009-10-23 6 views
11

Angenommen, Sie haben Abteilungen und Mitarbeiter und jede Abteilung hat mehrere Mitarbeiter, aber jeder Mitarbeiter kann auch Teil mehrerer Abteilungen sein.Regeln zum Löschen von Stammdaten und Viele-zu-Viele-Beziehungen

Es gibt also eine Viele-zu-Viele-Beziehung zwischen Mitarbeitern und Abteilungen. Beim Löschen einer Abteilung möchte ich alle Mitarbeiter löschen, die nur Teil dieser Abteilung sind, und die Beziehung zu dieser Abteilung für alle Mitarbeiter aufheben, die ebenfalls Mitglied einer anderen Abteilung sind.

Würde eine Kaskadenregel in beiden Richtungen das tun? Oder löscht eine Kaskadenregel automatisch alle Mitarbeiter einer Abteilung unabhängig von anderen Zugehörigkeiten?

Antwort

21

Eine Kaskadenregel löscht automatisch die Objekte am Zielort. Wenn Sie also eine Abteilung löschen, werden die Mitarbeiter unabhängig von der Anzahl der Abteilungen, in denen sie sich befinden, gelöscht.

Es klingt wie das Verhalten, das Sie wollen, ist ein wenig nuancierter, nur die "verwaisten" Mitarbeiter zu löschen - - also diejenigen, die keine Abteilung haben. Wenn Sie eine Abteilung löschen, wäre eine gute Art, diese zu finden, etwas in der Art zu tun:

NSManagedObject *doomedDepartment = // get the department to be deleted 

NSSet *employees = [doomedDepartment valueForKey:@"employees"]; 
NSSet *orphanedEmployees = [employees filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"[email protected] == 1"]]; 
for (NSManagedObject *orphanedEmployee in orphanedEmployees) { 
    [managedObjectContext deleteObject:orphanedEmployee]; 
}  

[managedObjectContext deleteObject:doomedDepartment]; 
5

Danke, alex. Das werde ich wahrscheinlich tun. In der Zwischenzeit hatte ich eine andere Art und Weise, dies zu tun gefunden:

1.) registrieren Sie sich für Benachrichtigungen über Änderungen:

[[NSNotificationCenter defaultCenter] addObserver:self 
      selector:@selector(managedObjectContextDidChange:) 
      name:NSManagedObjectContextObjectsDidChangeNotification 
      object:managedObjectContext]; 

2.), wenn Änderungen auftreten und Mitarbeiter aktualisiert wird. Ich überprüfe, ob das Objekt 0 Beziehungen zu Abteilungen hat und löschen:

- (void)managedObjectContextDidChange:(NSNotification *)notification { 
    NSSet *updatedObjects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey]; 

for(NSManagedObject *obj in updatedObjects){   
    // walk through updated objects -> check for employees 
    // check if they still contain departments and if not delete them 
    if([obj.entity.name isEqualToString:@"Employee"]){ 
     NSLog(@"Employee changed!"); 
     if([[(Employee*)obj Departments] count]==0){ 
      NSLog(@"No more relations -> Delete Employee"); 
      [managedObjectContext deleteObject:obj]; 
     } 
    } 
}} 

, das gut funktioniert auch, aber vielleicht komplizierter, wenn man für die mehrere verschiedene Entitäten haben diese Art von Verhalten zu beobachten.

+4

Wenn Sie mit Cocoa Touch oder Snow Leopard arbeiten, können Sie diese Logik in die 'prepareForDeletion'-Methode der Abteilung einfügen. –

+0

Ich denke, das ist eine bessere Lösung, danke! – Nick

+0

Wenn Sie Abteilung sagen, meinen Sie eine NSManagedObject-Anrufabteilung? – Ricardo