如何在NSPredicate中使用“ANY”聚合操作来过滤CoreData多对多关系

时间:2014-10-23 15:12:36

标签: ios objective-c core-data nspredicate

数据模型:

enter image description here

enter image description here

enter image description here

我正在尝试获取所有"解决方案"有contentType.selected == 1

证明结构和数据设置正确

- ContentType实体数据 Content Type Entity Data

- 解决方案实体数据

enter image description here

- ContentType关系

enter image description here

完整性检查(无谓词)

(lldb) po self.solutionTreeFetchedResultsController.fetchedObjects
<_PFArray 0x7fe958ea2b10>(
<Solutions: 0x7fe95b1415e0> (entity: Solutions; id: 0xd00000000ac00006 <x-coredata://2799F23D-B41B-48EF-923A-9E2C2A0C10B5/Solutions/p688> ; data: <fault>),
<Solutions: 0x7fe95b141b10> (entity: Solutions; id: 0xd00000000ac40006 <x-coredata://2799F23D-B41B-48EF-923A-9E2C2A0C10B5/Solutions/p689> ; data: <fault>)

......切断剩下的,但这里有49个。)

(lldb) po [self.solutionTreeFetchedResultsController.fetchedObjects count]
49

方法1(最直接)

NSArray *contentTypes = self.contentTypeFetchedResultsController.fetchedObjects;
request.predicate = [NSPredicate predicateWithFormat:@"ANY contentType IN %@", contentTypes];

po contentTypes
<_PFArray 0x7fa4b6018680>(
<ContentType: 0x7fa4b60181c0> (entity: ContentType; id: 0xd0000000006c0004 <x-coredata://2799F23D-B41B-48EF-923A-9E2C2A0C10B5/ContentType/p27> ; data: <fault>),
<ContentType: 0x7fa4b6018620> (entity: ContentType; id: 0xd000000000700004 <x-coredata://2799F23D-B41B-48EF-923A-9E2C2A0C10B5/ContentType/p28> ; data: <fault>)
)

po self.solutionTreeFetchedResultsController.fetchedObjects
<__NSArrayI 0x7fa4b3c1ddf0>(

)

方法2

 request.predicate = [NSPredicate
                         predicateWithFormat:@"SUBQUERY(contentType, $contenttype, $contenttype IN %@).@count = %d", contentTypes, [contentTypes count]];

(lldb) po self.solutionTreeFetchedResultsController.fetchedObjects
<__NSArrayI 0x7fcea3e01350>(

)

方法3

NSMutableArray *predicates = [[NSMutableArray alloc] init];
for (ContentType *contentType in contentTypes) {
    [predicates addObject:[NSPredicate predicateWithFormat:@"ANY contentType.name MATCHES %@", contentType.name]];
}

[predicates addObject:[NSPredicate predicateWithFormat:@"active == 1"]];
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];
request.predicate = compoundPredicate;

(lldb) po self.solutionTreeFetchedResultsController.fetchedObjects
<__NSArrayI 0x7f8f9850bbf0>(

)

如果您只选择1个contentType,则方法3 sorta有效,但如果您选择的内容超过1,则不返回任何内容。

我迷路了,不知道还有什么可以尝试的。任何投入将不胜感激!如果您还需要其他信息,请告诉我。谢谢!

从这篇文章尝试了大部分这些解决方案,似乎没有任何工作100% How to use the "ALL" aggregate operation in a NSPredicate to filter a CoreData-based collection

1 个答案:

答案 0 :(得分:1)

如果您的问题是如何获取所有&#34;解决方案&#34;具有给定数据模型的contentType.selected == 1,谓词:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(ANY contentType.selected == $SELECTVALUE)"];

适合我。将其定义为模板并将其添加到模型中....

- (NSManagedObjectModel *)managedObjectModel {
 // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
 if (_managedObjectModel != nil) {
     return _managedObjectModel;
 }
 NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"ANYApp" withExtension:@"momd"];

 _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

 NSEntityDescription *entity = [[_managedObjectModel entitiesByName] objectForKey:@"Solutions"];

 NSFetchRequest *template = [[NSFetchRequest alloc] init];

 [template setEntity:entity];

 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(ANY contentType.selected == $SELECTVALUE)"];

 [template setPredicate:predicate];

 [_managedObjectModel setFetchRequestTemplate:template forName:@"SolutionsTemplate"];

 return _managedObjectModel;
}

定义这样的抓取方法....

- (NSArray *)fetchAllSolutionsBySelected:(NSNumber *)selected
 {
  NSError *error = nil;

 NSString *templateName=@"SolutionsTemplate";

 NSDictionary *substitutionDictionary = [NSDictionary dictionaryWithObjectsAndKeys:selected, @"SELECTVALUE", nil];

 NSFetchRequest *fetchRequest = [[_app managedObjectModel] fetchRequestFromTemplateWithName:templateName substitutionVariables:substitutionDictionary];

 NSArray *results = [[_app managedObjectContext] executeFetchRequest:fetchRequest error:&error];

 return results;
}

我终于可以获取所有&#34;解决方案&#34;有contentType.selected == 1:

NSArray *solutionsWithContentSelected=[self fetchAllSolutionsBySelected:@(1)];

您可以在此处找到XCode 6.1 iOS 8.1项目:ANYApp Project。我希望它有所帮助。