문제

NSARRAYCONTROLLER가 있습니다. companiesController 최상위 핵심 데이터 엔티티에 묶여 Companies.

Company 많이있다 DepartmentS, a Department 많이있다 Employee; 이들은 1 대가 된 관계로 표현되며 departments 그리고 employees.

속성을 기반으로합니다 salaryEmployee UI 통한 방법 내부의 급여를 기준으로 필터링을 위해 동적으로 할 수 있다고 생각했습니다.

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

아아, 이것은 나에게 오류를 준다 : -[NSCFSet compare:]: unrecognized selector sent to instance.

도움이 되었습니까?

해결책

이 경우 여러 대의 키가 허용되지 않습니다.

대신 다음을 수행 할 수 있습니다.

  1. 부서 엔티티에 "필터"플래그 (부울) 속성을 추가하여 데이터 모델을 수정하십시오.
  2. 메소드를 만듭니다 : 모든 부서 개체를 가져와, 술어의 후반기 기준을 충족하는 부서의 경우 필터 플래그를 YES로 설정하고 다른 부서의 경우 필터 플래그를 NO로 설정하고 저장하십시오.
  3. 회사 술어에서 필터 플래그를 사용하십시오.

코드 변경 (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];

그리고 새로운 방법 (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();
    } 
}

다른 팁

하위 쿼리를 사용 하여이 작업을 수행 할 수도 있습니다.

모든 부서를 구입하십시오. '관계는'관계는 회사의 부서의 역수입니다.

-(void)printDepartmentsWithSalaryHigherThan:(int)salary inContext:(NSManagedObjectContext *)context {    
    NSFetchRequest *request = [[NSFetchRequest alloc ]init];
    request.entity = [NSEntityDescription entityForName:@"Department" inManagedObjectContext:context];
    request.predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(employees, $emp, $emp.salary > %@ ).@count > 0", [NSNumber numberWithInt:salary]];

    for(Department *dep in [context executeFetchRequest:request error:nil]){
        NSLog(@"Department: %@", dep.depName);
        NSLog(@"in Company: %@", dep.of.compName);
    }
    [request release];
}

또는 더 많은 회사가 있고 급여를받는 직원이있는 회사를 원하는 경우, 일부 금액보다 더 높습니다. 하위 퀘스트의 결과를 기반으로 한 하위 퀘스트

-(void)printCompaniesWithHigherSalaryThan:(int)salary inContext:(NSManagedObjectContext *)context {
    NSFetchRequest *request = [[NSFetchRequest alloc ]init];
    request.entity = [NSEntityDescription entityForName:@"Company" inManagedObjectContext:context];
    request.predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(departments, $dep, SUBQUERY($dep.employees,$emp,$emp.salary > %@).@count > 0 ).@count > 0", [NSNumber numberWithInt:salary]];

    for(Company *c in [context executeFetchRequest:request error:nil]){
        NSLog(@"Company: %@", c.compName);
    }
    [request release];
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top