将NSPredicate与Core Data结合使用以实现深层关系 [英] Using NSPredicate with Core Data for deep relationships
问题描述
我有一个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.
您可以执行以下操作:
- 修改数据模型向Department实体添加filter标志(布尔)属性。
- 创建一个方法来:获取所有的部门对象,将满足您的谓词后半部分条件的部门的过滤器标记设置为YES,将过滤器标记设置为NO其他部门,并保存。
- 在公司谓词中使用过滤器标记。
代码更改(步骤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屋!