NSPredicate 使用 CoreData 进行多个 ANY 查询

Posted

技术标签:

【中文标题】NSPredicate 使用 CoreData 进行多个 ANY 查询【英文标题】:NSPredicate multiple ANY query with CoreData 【发布时间】:2013-11-19 15:58:55 【问题描述】:

我正在尝试查找对象的所有实例,这些实例包含对我的对象图中的单独对象组合的引用。

recommendation

可能包含以下三个对象中的一个或多个:

damageType

areaDamaged

validVehicles

此结构是从现有系统文件格式的导入构建的,我无法重新构建对象图。

我正在使用NSPredicate 来查找所有recommendation 对象与damageType 匹配的选定损坏如下:

NSFetchRequest *fetchRequestDamages = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([Recommendation class])];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY damageType == %@", _currentRecordedDamage.damageType];

但希望过滤器返回与特定damageTypeareaDamagedvalidVehicle 匹配的所有Recommendations

我试过了

NSMutableArray *predicates = [[NSMutableArray alloc] initWithCapacity:2];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY damageType == %@", _currentRecordedDamage.damageType];
        [predicates addObject:predicate];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"ANY areaDamaged == %@", _currentAreaDamaged];
        [predicates addObject:predicate2];
NSPredicate *predicate3 = [NSPredicate predicateWithFormat:@"ANY validVehicles == %@", _currentVehicle];
        [predicates addObject:predicate3];


fetchRequestDamages.predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];


fetchRequestDamages.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];

self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequestDamages managedObjectContext:[RKManagedObjectStore defaultStore].mainQueueManagedObjectContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController.delegate = self;

NSError *error;

[self.fetchedResultsController performFetch:&error];
 int resultsFound = self.fetchedResultsController.fetchedObjects.count;

但这似乎返回满足任何谓词的所有对象的集合 - 我想要匹配所有三个的对象集合。

我正在考虑使用 SUBQUERY,但不太明白如何创建此查询?

【问题讨论】:

执行获取请求的代码是什么? @davbryn:所以你已经按照我下面的建议做了。 - 也许你可以举一个例子来说明你目前得到了什么以及你期望什么。 damageType 和 areaDamaged 和 validVehicles to-many 关系是否来自推荐?如果不是简单地选择 AndrewShmigs。如果是,那么您将需要子查询。 @FelixLam 是的,它们都是对多的 也许看看我在这里给出的回复:***.com/questions/3725936/… 【参考方案1】:

只需将三个谓词与“AND”结合起来即可找到与所有谓词匹配的对象:

NSArray *predicates = ... // your array of predicates
NSPredicate *finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];
[fetchRequestDamages setPredicate:finalPredicate];    

【讨论】:

当我拥有三个 AND 谓词时,它会返回一个集合,其中包含的建议在其集合中没有 validVehicle 匹配项(但确实与另一个属性匹配)。 @davbryn:这很奇怪。它应该只返回满足所有三个子谓词的对象。 - 您是否分别测试了所有三个谓词? 这不是他在代码中所做的吗? fetchRequestDamages.predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates]; @FelixLam:是的,但我只有在他用这些信息更新问题后才知道。 这个答案是正确的 - 问题(遗憾的是)是谓词全部匹配 - 存在将对象链接到所有三个要求的导入器错误。我通过单独运行谓词并调查关系来发现它【参考方案2】:

为什么不在一个查询中使用 AND? 比如:

damage = %@ AND damagePoints = %@ AND damageCost = %@

和:

damageType IN %@

最后一个代码示例中的 %@ 应该是一个数组/集合或其他东西。

【讨论】:

使用复合谓词更加简洁 @DavidCaunt,如果你有 2-3 个语句 - 可以使用一体式,否则你绝对应该使用复合谓词。

以上是关于NSPredicate 使用 CoreData 进行多个 ANY 查询的主要内容,如果未能解决你的问题,请参考以下文章

NSPredicate,CoreData 中的空格。如何修剪谓词?

如何使用 NSPredicate 从 CoreData 中删除选定数量的行?

在 Swift 中使用 NSPredicate 显示 CoreData 的结果

在 Swift 中使用 NSPredicate 对 CoreData 结果进行排序

使用 NSPredicate 根据数组属性过滤 CoreData 项列表

CoreData NSPredicate