2009-10-23 13 views
11

Załóżmy, że masz działy i pracowników, a każdy dział ma kilku pracowników, ale każdy pracownik może być również częścią kilku działów.Reguły usuwania danych podstawowych i relacje wiele-wiele

Istnieje wiele relacji między pracownikami i działami. Usuwając dział, chciałbym usunąć wszystkich pracowników, którzy są tylko częścią tego działu i unieważnić relacje z tym działem dla wszystkich pracowników, którzy są również członkami innego działu.

Czy reguła kaskadowa w obu kierunkach to zrobi? A może reguła kaskadowa automatycznie usuwa wszystkich pracowników działu bez względu na inne powiązania?

Odpowiedz

21

Reguła kaskady automatycznie usunie obiekty w miejscu docelowym. Jeśli usuniesz dział, pracownicy zostaną usunięci bez względu na liczbę oddziałów, w których się znajdują.

Wygląda na to, że pożądane zachowanie jest nieco bardziej zniuansowane, aby usunąć tylko "osieroconych" pracowników - - czyli takie, które nie mają działu. Po usunięciu działu dobrym sposobem na znalezienie takich informacji jest zrobienie czegoś takiego:

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

Dzięki, alex. Prawdopodobnie to zrobię. W międzyczasie znalazłem inny sposób to zrobić:

1.) zarejestrować się na powiadomienia o zmianach:

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

2.), gdy występują zmiany i pracownik zostanie zaktualizowany. I sprawdzić, czy ten obiekt ma 0 relacji do wydziałów i usunąć go:

- (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]; 
     } 
    } 
}} 

To działa zbyt dobrze, ale może się bardziej skomplikowana, jeśli masz kilka różnych podmiotów, dla których obserwować tego rodzaju zachowania.

+4

Jeśli pracujesz nad Cocoa Touch lub Snow Leopard, możesz umieścić tę logikę w metodzie '-prepareForDeletion'. –

+0

Myślę, że to lepsze rozwiązanie, dzięki! – Nick

+0

Kiedy mówisz o wydziale, masz na myśli dział połączeń NSManagedObject? – Ricardo

Powiązane problemy