Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何计算与一对多关系的查询匹配的核心数据实体?_Ios_Core Data_Count_Group By_Entity - Fatal编程技术网

Ios 如何计算与一对多关系的查询匹配的核心数据实体?

Ios 如何计算与一对多关系的查询匹配的核心数据实体?,ios,core-data,count,group-by,entity,Ios,Core Data,Count,Group By,Entity,假设我有两个核心数据实体。学生实体和班级实体。例如,一个学生正好在一个班级,一个班级可以有许多学生 让我们也假设这些是大类。也就是说,每个班有1000名学生 类实体看起来像: NSString* name NSArray* students 学生实体: NSString* name Class* class NSString* grade 在我的UI中,我想显示一个类。我想显示有一定成绩的学生人数。也就是说,对于1000名学生的班级,50名学生得a,500名学生得B,200名学生得C。。。等

假设我有两个核心数据实体。学生实体和班级实体。例如,一个学生正好在一个班级,一个班级可以有许多学生

让我们也假设这些是大类。也就是说,每个班有1000名学生

类实体看起来像:

NSString* name
NSArray* students
学生实体:

NSString* name
Class* class
NSString* grade
在我的UI中,我想显示一个类。我想显示有一定成绩的学生人数。也就是说,对于1000名学生的班级,50名学生得a,500名学生得B,200名学生得C。。。等等

从核心数据中获取这些计数的最有效方法是什么

我是最新的;y使用NSFetchedResultsController并向其传递GROUPBY+count查询的获取请求。我正在使用NSFetchedResultsController,以便UI随着具有特定等级的学生数量的变化而更新。不过速度很慢

有没有一种不用查询就能获得这些信息的方法?也就是说,当学生被添加到班级或他们的成绩发生变化时,班级上的一个属性将更新为所有成绩计数。因此,当我需要计数时,它们只是类的一个属性,不需要查询


有可能吗?

您可以使用以下示例获取给定条件下的计数。您不需要提取数据进行计数。您可以使用
countForFetchRequest
方法有效地对对象进行计数

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:moc]];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:
        @"grade=='A'"];
    [request setPredicate:predicate];

    NSError *err;
    NSUInteger count = [moc countForFetchRequest:request error:&err];
    if(count == NSNotFound) {
      //Handle error
    }

    [request release];

您可以尝试此提取请求:

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Student"];
[request setResultType:NSDictionaryResultType];
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"grade"];
NSExpression *countExpression = [NSExpression expressionForFunction:@"count:" arguments:[NSArray arrayWithObject:keyPathExpression]];

NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName:@"gradeTypeCount"];
[expressionDescription setExpression:countExpression];
[expressionDescription setExpressionResultType:NSInteger64AttributeType];
[request setPropertiesToFetch:@[@"grade",expressionDescription]];
[request setPropertiesToGroupBy:@[@"grade"]];
[request setPredicate:[NSPredicate predicateWithFormat:@"theClass == %@",cls.objectID]];
这将产生一个包含所需值的字典数组。
这里的问题是,您的FRC将无法跟踪这些结果的变化。因此,没有理由首先使用FRC
即便如此,这是一个非常轻量级的请求,您可以在给定的时间间隔发出请求并更新UI

(比如说2秒,由于您不再处理托管对象,因此您可以在后台完成整个过程,并将结果转储到主线程中)(如您所愿)

或者收听主上下文的更改,如果学生元素发生更改,则重新提取计数。


这将避免获取所有
学生
元素(按所述成本)。

这是swift中最简单的方法

let request = NSFetchRequest(entityName: "BWCoreDataNotification")
request.predicate = NSPredicate(format: "type = 'purchase_reward'")

var error: NSError?
let numberOfNotifications = NSManagedObjectContext.MR_defaultContext().countForFetchRequest(request, error: &error)

我如何监控这些计数的变化?另外,countForFetchRequest与常规提取相比,其性能特点是什么?您可以使用与fetchrequestcontroller相同的NSFetchrequstcontroller进行countForRetchRequest。这比常规获取更有效。您不必获取所有数据来获取计数。我认为NSFetchedResultsController中没有方法countForFetchRequest为什么不可以使用fetchrequest控制器监视更改。对于exmaple controllerDidChangeContent委托方法,我可以这样做,事实上这是我已经在做的事情。但是它太慢了,因为您必须通过NSFetchedResultsController和fetchRequest,然后它会启动并执行1000个学生的整个提取。据我所知,没有办法告诉NSFetchedResultsController使用CountForFetchRequest如果您使用FRC,请添加排序描述符。我最后只使用了您提供的group by fetch请求,然后列出对moc的更改,以便在需要时再次运行该请求