首页 文章

核心数据基于'ordered'关系的属性进行提取

提问于
浏览
3

我的应用程序具有类似功能的智能文件夹:谓词是使用NSPredicateEditor设置的,用于使用获取请求填充文件夹 .

搜索中使用的实体具有多对多关系 . 在索引存储在目标实体中以进行排序的意义上,关系是有序的 .

我的问题是我想基于有序关系中的最后一个值构建一个规则,但我无法弄清楚如何构建一个谓词来执行此操作,因为该关系不是一个数组 . 核心数据实际上并不知道订单 .

我在类上有一个readonly属性,它返回有序的项目,但这似乎对获取请求没有帮助,因为该属性在核心数据存储中不可用 .

我能想到的唯一选择是对单独属性中订购的关系中的最后项进行去规范化和存储 . 这是唯一的解决方案吗?

2 回答

  • 2

    好吧,假设我已经正确理解了问题,我会这样做 . 假设你有两个实体,TopEntity有一个(NSString *)name属性和一个与MyEntity的to-many关系,它有一个(NSString *)数据属性和(NSInteger)顺序属性 .

    假设您想要匹配给定字符串的TopEntity对象,并且其MyEntity订单满足某个条件,那么您可以使用两个谓词和NSFetchRequest这样做....

    NSManagedObjectContext *context = [self managedObjectContext];
    
    // Create some top level entities
    TopEntity *aTop = [TopEntity insertInManagedObjectContext:context];
    aTop.name = @"This is Your Name";
    TopEntity *bTop = [TopEntity insertInManagedObjectContext:context];
    bTop.name = @"This aint a Name";    
    TopEntity *cTop = [TopEntity insertInManagedObjectContext:context];
    cTop.name = @"This is My Name";    
    
    // Add some data
    NSInteger i, len = 30;
    for(i=0; i<len; i++) {
        // Create a new object
        MyEntity *entity = [MyEntity insertInManagedObjectContext:context];
        entity.orderValue = i;
        entity.data = [NSString stringWithFormat:@"This is some data: %d", i];
        if(i < 10) {
            [aTop addObjectsObject:entity];
            [entity addTopObject:aTop];
        } else if (i < 20) {
            [bTop addObjectsObject:entity];
            [entity addTopObject:bTop];            
        } else {
            [cTop addObjectsObject:entity];
            [entity addTopObject:cTop];                        
        }
    }
    
    // Save the context
    NSError *error = nil;
    [context save:&error];
    
    // A predicate to match against the top objects
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH %@", @"This is"];
    // A predicate to match against the to-many objects
    NSPredicate *secondPredicate = [NSPredicate predicateWithFormat:@"ANY objects.order < %d", 5];
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
    [fetch setEntity:[NSEntityDescription entityForName:@"TopEntity" inManagedObjectContext:context]];
    [fetch setPredicate:predicate];
    NSArray *result = [[context executeFetchRequest:fetch error:&error] filteredArrayUsingPredicate:secondPredicate];
    
    
    for(TopEntity *entity in result) {
        NSLog(@"entity name: %@", entity.name);         
    }
    

    因此,基本上您可以使用另一个谓词包装获取请求的结果并使用ANY关键字 .

    我不知道它有多高效,但它适用于这种情况 . 运行上面将输出“这是你的名字”,即它匹配第一个TopEntity .

  • 1

    我只是在获取请求级别上限制n个结果的方法 .

    除了引用你提到的关系中的最后n个项目之外,你可以尝试一个布尔属性“lastN”并在你策划列表的顺序时打开/关闭它们(比如,在用户启动的排序或拖动 - 和 - 下降重新排序) .

    或者,您可以为按排序键排序的每个搜索事物创建单独的获取请求,按顺序降序,并限制(通过-setFetchLimit :)到n个结果 .

    将此作为关系或属性进行跟踪有点“混乱”,而获取限制更昂贵(因为多次往返) . 如果您的重新排序是通过一次性用户操作完成的,那么使用关系或属性方法可能会提高性能,因为工作是分摊的,而不是在一系列提取中一次性完成 . 我自己没有找到更好的方法,并会密切关注这一点 . :-)

相关问题