首页 文章

核心数据 - 使用谓词过滤多对多关系

提问于
浏览
12

我的核心数据模型中有以下两个实体:

Manufacture {name, ...other attributes}
Product {name, .... other attributes}

我 Build 了一对多的关系:

Manufacturer.manufactures <------>> Product.manufacturedBy

我正在尝试构建一个谓词,以返回属于制造商的所有匹配搜索字符串的产品 . 例如 . 如果有两个制造商,“国王坚果”和“女王坚果”,那么搜索“坚果”应该返回国王坚果和女王坚果制作的所有产品 .

当我的过滤器在Product实体上时,我的谓词工作正常,但是当在Manufacturer实体上过滤时,我无法获得任何谓词 . 结果集为空 .

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Product" inManagedObjectContext:[GBKDB context]];
searchValue = @"nut";
NSString *wildcardString = [NSString stringWithFormat:@"*%@*", searchValue];

我尝试过以下方法:

predicate = [NSPredicate predicateWithFormat:@"manufacturedBy.name CONTAINS[cd] %@",searchValue];
    predicate = [NSPredicate predicateWithFormat:@"manufacturedBy.name like %@",wildcardString];
    predicate = [NSPredicate predicateWithFormat:@"manufacturedBy.name matches %@",wildcardString];
    predicate = [NSPredicate predicateWithFormat:@"ALL manufacturedBy.name like %@",wildcardString];
    predicate = [NSPredicate predicateWithFormat:@"ALL manufacturedBy.name like[cd] %@",@wildcardString];

2 回答

  • 4

    要获得名称包含"nut"的制造商 生产环境 的 Product ,您的请求应如下所示:

    NSString* searchVal = @"nut";
    NSFetchRequest* r = [[NSFetchRequest alloc] initWithEntityName:@"Product"];
    [r setPredicate:[NSPredicate predicateWithFormat:@"manufacturedBy.name CONTAINS[cd] %@",searchVal]];
    

    要获得包含"nut"的产品名称的 Manufacturer ,您的请求应如下所示:

    NSString* searchVal = @"nut";
    NSFetchRequest* r = [[NSFetchRequest alloc] initWithEntityName:@"Manufacture"];
    [r setPredicate:[NSPredicate predicateWithFormat:@"ANY manufactures.name CONTAINS[cd] %@",searchVal]];
    

    如果结果集为空,则可能是因为没有对象回答谓词(包含子字符串"nut") .
    尝试添加一些具有已知名称和测试的假实体 .

    Edit: 这是您可以用于测试的代码:

    typedef void(^config_block_t)(id);
    
    - (void) synthesizeObjectsOfEntity:(NSString*)entity
                               context:(NSManagedObjectContext*)context
                                 count:(NSUInteger)count
                           configBlock:(config_block_t)configBlock
    {
        for (;count;--count) {
            NSManagedObject* object = [NSEntityDescription insertNewObjectForEntityForName:entity
                                                                    inManagedObjectContext:context];
            configBlock(object);
        }
    }
    
    - (void) synthesizeProductsAndManufacturersInContext:(NSManagedObjectContext*)context
    {
        NSMutableArray* manufacturers = [NSMutableArray new];
        [self synthesizeObjectsOfEntity:@"Manufactur"
                                context:context
                                  count:10
                            configBlock:^(Manufactur* m) {
                                m.name = [NSString stringWithFormat:@"m-%u%u%u",arc4random()%10,arc4random()%10,arc4random()%10];
                                [manufacturers addObject:m];
                            }];
        [self synthesizeObjectsOfEntity:@"Product"
                                context:context
                                  count:100
                            configBlock:^(Product* p) {
                                p.name = [NSString stringWithFormat:@"p-%u%u%u",arc4random()%10,arc4random()%10,arc4random()%10];
                                p.manufacturedBy = manufacturers[arc4random() % [manufacturers count]];
                            }];
        [context save:NULL];
        [context reset];
        NSString* searchVal = @"3";
        NSFetchRequest* r = [[NSFetchRequest alloc] initWithEntityName:@"Product"];
        [r setPredicate:[NSPredicate predicateWithFormat:@"manufacturedBy.name CONTAINS[cd] %@",searchVal]];
        NSArray* match = [context executeFetchRequest:r error:NULL];
        NSLog(@"matched: %u",[match count]);
    }
    
  • 18

    看一下Apple的this文档 . 它做了一个例子来做你正在尝试用"ANY"谓词做的事情 .

相关问题