【问题标题】:How to use the “ANY” aggregate operation in a NSPredicate to filter a CoreData Many To Many Relationship如何在 NSPredicate 中使用“ANY”聚合操作来过滤 CoreData 多对多关系
【发布时间】:2014-12-19 07:31:28
【问题描述】:

数据模型:

我正在尝试获取所有具有 contentType.selected == 1 的“解决方案”

证明结构和数据设置正确

--ContentType 实体数据

--解决方案实体数据

--ContentType 关系

健全性检查(无谓词)

(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>(

)

方法二

 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 排序有效,但如果您选择了 1 个以上,则它不会返回任何内容。

我迷路了,不知道还能尝试什么。任何投入将不胜感激!如果您还需要什么,请告诉我。谢谢!

已经尝试了这篇文章中的大多数解决方案,但似乎没有任何方法 100% 有效 How to use the "ALL" aggregate operation in a NSPredicate to filter a CoreData-based collection

【问题讨论】:

    标签: ios objective-c core-data nspredicate


    【解决方案1】:

    如果您的问题是如何使用给定的数据模型获取所有具有 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;
    }
    

    像这样定义 fetch 方法 ....

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

    我终于可以获取所有具有 contentType.selected == 1 的“解决方案”:

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

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

    【讨论】:

    • 非常感谢!效果很好! "request.predicate = [NSPredicate predicateWithFormat:@"(ANY contentType.selected == 1)"];"
    猜你喜欢
    • 2011-07-15
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多