将NSPredicate与Core Data结合使用以实现深层关系 [英] Using NSPredicate with Core Data for deep relationships

查看:138
本文介绍了将NSPredicate与Core Data结合使用以实现深层关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个NSArrayController, companiesController 绑定到顶级Core Data实体 Companies

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

A 公司有许多部门 部门有许多员工;这些由1对多关系, departments employees 表示。

A Company has many Department's, and a Department has many Employee; these are represented by the 1-to-many relationships, departments and employees.

根据员工 I的属性 salary 我认为我可以动态地做这个过滤基于工资内UI的方法:

Based on the attribute salary of an Employee I thought I could dynamically do this for filtering based on salary inside a UI-called method:

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

唉,这给我错误: - [NSCFSet compare:]:

Alas, this gives me the error: -[NSCFSet compare:]: unrecognized selector sent to instance.

推荐答案

在这种情况下不允许使用多对多键。

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

您可以执行以下操作:


  1. 修改数据模型向Department实体添加filter标志(布尔)属性。

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

这篇关于将NSPredicate与Core Data结合使用以实现深层关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆