根据对多关系中相关对象的计数对获取请求进行排序

Posted

技术标签:

【中文标题】根据对多关系中相关对象的计数对获取请求进行排序【英文标题】:Sorting a fetch request based on count of related object in to-many relationship 【发布时间】:2015-12-14 00:04:59 【问题描述】:

需要按类别拥有的产品数量/计数对通过 fetch 请求检索到的类别列表进行排序。然后,我希望能够手动将几个类别(被过滤掉)添加到数组中,以便它们位于列表的底部。当我尝试按产品数量进行排序时,我一直遇到“包含 KVC 聚合的 Keypath 不应该有...”的错误。

我在这里错过了什么/做错了什么?谢谢!

类别.h

@class Category;

@interface Category : NSManagedObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSSet *products;

@end

产品.h

@class Category;

@interface Product : NSManagedObject

@property (nonatomic, strong) NSString *sku;
@property (nonatomic, strong) NSString *name; // Product name
@property (nonatomic, strong) NSString *prodDescription;
@property (nonatomic, strong) Category *category; // Product category
@property (nonatomic, strong) NSString *upc;
@property (nonatomic, strong) NSString *countryCode;
@property (nonatomic, strong) NSString *webpage;
@property (nonatomic, strong) NSString *manual;
@property (nonatomic, strong) NSString *quickStart;
@property (nonatomic, strong) UIImage *thumb;
@property (nonatomic, strong) NSString *thumbURLString;
@property (nonatomic, strong) UIImage *mainImg;
@property (nonatomic, strong) NSString *mainImgURLString;
@property (nonatomic, strong) UIImage *secondaryImg;
@property (nonatomic, strong) NSString *secondaryImgURLString;

@end

CategoriesViewController.m

- (NSFetchedResultsController *)fetchedResultsController 

    if (_fetchedResultsController == nil) 
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        [fetchRequest setEntity:[NSEntityDescription entityForName:@"Category" inManagedObjectContext:self.managedObjectContext]]; // Fetch categories
        NSArray *sortDescriptors = nil;
        NSString *sectionNameKeyPath = nil;
        // Sort by number of products in category
        sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"category.@count" ascending:NO]];
        [fetchRequest setSortDescriptors:sortDescriptors];

        // Use predicate to exclude Accessories and Replacement Parts categories from initial array
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name != 'Accessories' AND name != 'Replacement Parts'"];
        [fetchRequest setPredicate:predicate];

        _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                                                    managedObjectContext:self.managedObjectContext
                                                                      sectionNameKeyPath:sectionNameKeyPath
                                                                               cacheName:nil];

        
    return _fetchedResultsController;

【问题讨论】:

【参考方案1】:

你应该使用这样的一对多关系

【讨论】:

【参考方案2】:

通常,这可以通过在记录本身中添加一个计数变量来解决。这允许获取的结果控制器对该计数的值进行排序。我在相关关系的自定义设置器中维护这种计数。在您的情况下,这可能是products 的集合,新变量可能称为productCount。 Xcode 为这类事情提供了一个 sn-p 模板。这是一个例子:

- (void) addProductsObject: (Product *) value 

    NSSet *changedObjects = [NSSet setWithObject:value];

    [self willChangeValueForKey: kDays withSetMutation: NSKeyValueUnionSetMutation usingObjects: changedObjects];
    [[self primitiveValueForKey: kDays] addObject: value];
    [self  didChangeValueForKey: kDays withSetMutation: NSKeyValueUnionSetMutation usingObjects: changedObjects];

    self.productCount = (int32_t)self.products.count;

 // -addProductsObject:

其他三种方法同样简单。

【讨论】:

以上是关于根据对多关系中相关对象的计数对获取请求进行排序的主要内容,如果未能解决你的问题,请参考以下文章

根据关系属性对获取请求进行排序

以多对多关系对相关集进行排序

从多对多关系中获取核心数据

从核心数据获取请求中排除反向关系

iPhone:无法对多对关系进行 NSSortDescriptor。如何排序?

对核心数据请求进行升序排序