过滤 NSManagedObject 的关系
Posted
技术标签:
【中文标题】过滤 NSManagedObject 的关系【英文标题】:Filtering a relationship of an NSManagedObject 【发布时间】:2012-05-21 10:01:50 【问题描述】:假设Manager
与Employee
对象具有一对多关系。给定对Manager
对象的引用(即NSManagedObject *manager
),我如何获得对“所有薪水超过10000 的人中薪水最低的Employee
”的引用?
我可以想到两种可能的方法:
方法 1:构造一个 NSFetchRequest
并使用相关 Manager
的对象 ID 指定所需的 Manager
。
方法 2:Manager
上的某种键值编码表达式,例如[manager valueForKeyPath:@"..."]
(使用了NSPredicate
?)
如果有可行的解决方案,我倾向于方法 2。请赐教。
【问题讨论】:
【参考方案1】:当然,您可以将谓词和排序描述符应用于关系返回的集合。如果集合相对较小(因为它是在内存中完成的,所有对象都必须被获取),那么简单且非常快。您可能希望预先执行该批处理以限制执行 I/O 的次数。
根据数据库的大小和经理(以及索引)下的员工数量,您可能希望在数据库级别完成所有操作...
// We want "Employee" objects
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
// Assuming the "inverse" relationship from employee-to-manager is "manager"...
// We want all employees that have "our" manager, and a salary > 10000
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(manager == %@) AND (salary > 10000", manager];
// Sort all the matches by salary, little-to-big
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"salary" ascending:YES]];
// Limit the returned set to 1 object, which will be the smallest
fetchRequest.fetchLimit = 1;
这将在数据库级别执行整个查询,并且只返回 1 个对象。
与往常一样,性能问题通常高度依赖于您的模型布局,以及用于指定模型及其关系的选项。
【讨论】:
【参考方案2】:您可以过滤您的Employee
关系数组以获得您想要的关系。
1)首先,获取所有工资超过10000的Employee
:
NSArray *filtered = [manager.employees filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(salary > 10000)"]];
2)然后按降序排序
NSSortDescriptor* sortOrder = [NSSortDescriptor sortDescriptorWithKey: @"salary" ascending: NO];
NSArray *sortedAndFiltered = [filtered sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];
3)然后找你的员工
[sortedAndFiltered lastObject];
【讨论】:
以上是关于过滤 NSManagedObject 的关系的主要内容,如果未能解决你的问题,请参考以下文章
如何观察 NSManagedObject 是不是从 managedObjectContext 中移除
NSManagedObject 类关系中的 NSPredicate 键
如何在 CoreData 的代码中设置 NSManagedObject 与另一个 NSManagedObject 或它们的堆栈的关系?