Using NSPredicate with Core Data for deep relationships

前端 未结 2 728
无人及你
无人及你 2020-12-28 21:20

I have an NSArrayController, companiesController bound to a top level Core Data entity, Companies.

A Company has many D

2条回答
  •  被撕碎了的回忆
    2020-12-28 21:51

    Multiple to-many keys are not allowed in this case.

    Instead, you could do the following:

    1. Modify the data model by adding a "filter" flag (Boolean) attribute to the Department entity.
    2. Create a method to: fetch all the Department objects, set the filter flag to YES for the departments that meet the criteria of the second half of your predicate, set the filter flag to NO for the other departments, and save.
    3. Use the filter flag in the Company predicate.

    Code changes (step 3):

        //NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY departments.employees.salary < %@", [NSNumber numberWithInt:23000]];
        [self setDeptFilter:23000];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY depts.filter == YES"];
        [companiesController setFilterPredicate:predicate];
    

    And the new method (step 2):

    - (void)setDeptFilter:(NSUInteger)salary {
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Department" inManagedObjectContext:self.managedObjectContext];
        [fetchRequest setEntity:entity];
    
        NSError *error = nil;
    
        // fetch all Department objects
        NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    
        [fetchRequest release];
    
        if (error) {
            NSLog(@"Error fetching Departments %@, %@", error, [error userInfo]);
            abort();
        }
    
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY emps.salary < %@",[NSNumber numberWithInteger:salary]];
        NSArray *filterArray = [array filteredArrayUsingPredicate:predicate];
    
        // set filter flag to YES for the departments that meet the criteria
        for (Department *dep in filterArray) {
            dep.filter = [NSNumber numberWithBool:YES];
        }
    
        NSMutableArray *diffArray = [array mutableCopy];
        [diffArray removeObjectsInArray:filterArray];
    
        // set filter flag to NO for the departments that do NOT meet the criteria
        for (Department *dep in diffArray) {
            dep.filter = [NSNumber numberWithBool:NO];
        }
    
        [diffArray release];
    
        // save
        if ([self.managedObjectContext hasChanges] && ![self.managedObjectContext save:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        } 
    }
    

提交回复
热议问题