0

我有一个模型:

Place:
title
address
category <--->> Category:
                title

我希望有一个表格视图,其中部分作为类别名称,但能够根据地点标题进行搜索。现在,为仅具有与某些指定 searchText 匹配的类别和标题的表视图获取一组数据的最佳方法是什么?我目前将结果放在 NSDictionary 中,但它似乎效率不高。特别是在执行删除类型操作时 - 我遇到了很多问题。目前我正在执行以下操作,但更愿意直接返回 FetchedResultsController。

+ (NSMutableDictionary *)getDictionaryResultsInContext: (NSManagedObjectContext *)context
                                         forSearchText: (NSString *)searchText {

    NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Place"];
    if(![searchText isEqualToString:@""] && searchText != nil){
        req.predicate = [NSPredicate predicateWithFormat:@"(category.name CONTAINS[cd] %@) OR (placeTitle CONTAINS[cd] %@) OR (details CONTAINS[cd] %@)", searchText, searchText, searchText];
        NSLog(@"ModelHelper.getResults: Search text given, creating predicate: %@", req.predicate);
    }
    req.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"placeTitle"
                                                                                 ascending:YES
                                                                                  selector:@selector(localizedCaseInsensitiveCompare:)]];
    NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]initWithFetchRequest:req
                                                                                managedObjectContext:context
                                                                                  sectionNameKeyPath:nil
                                                                                           cacheName:nil];
    NSError *error = nil;
    [controller performFetch:&error];
    if (error) {
        NSLog(@"- Model Search ERROR: %@ (%@)", [error localizedDescription], [error localizedFailureReason]);
    }

    NSLog(@"- Got results: %i", [controller.fetchedObjects count]);

    NSMutableDictionary* ret = [[NSMutableDictionary alloc]init];

    for(Place* obj in controller.fetchedObjects){
        if(obj != nil){
            NSManagedObjectID* categoryId = obj.category.objectID;
            if(categoryId != nil){
                NSMutableArray* ary = (NSMutableArray*)[ret objectForKey:categoryId];
                if(ary == NULL){
                    ary = [[NSMutableArray alloc]init];
                    [ret setObject:ary forKey:categoryId];
                }
                [ary addObject:obj];
            }
            else {
                // Shouldnt happen
                NSLog(@"- Category was nil.");
            }
        }
        else {
            // Shouldnt happen
            NSLog(@"- Place was nil.");
        }
    }

    return(ret);
}
4

1 回答 1

0

您的数据模型没有意义。你真的想要一个多对多的关系。

类别只有在可以包含多个地点时才有意义。所以category->place关系必须是对多的。可选地,一个地方可以属于多个类别,place->category也可以属于多个类别;如果不是,它应该是一对一的关系。

所以要么

Place <<----------> Category

或者

Place <<--------->> Category

但不是您问题中的版本。在您的场景中,作为餐厅的地方将获得标题为“餐厅”的类别,而对于下一个为餐厅的地方,您必须创建一个标题为“餐厅”的新类别。没有意义。

在简单的情况下(一对多),您的谓词是

[NSPredicate predicateWithFormat:
  @"title CONTAINS[cd] %@ OR address CONTAINS[cd] %@", searchTerm, searchTerm];

对于更复杂的情况(多对多),您会遇到一个地方可以在多个部分中列出的问题。因此,您必须获取类别,使用类别位置的计数作为每个部分中的行数,并使用此谓词进行过滤:

[NSPredicate predicateWithFormat:
  @"ANY places.title CONTAINS[cd] %@ OR ANY places.address CONTAINS[cd] %@",
  searchTerm, searchTerm]; 
于 2013-04-22T14:52:43.383 回答