Ios 如何计算与一对多关系的查询匹配的核心数据实体?
假设我有两个核心数据实体。学生实体和班级实体。例如,一个学生正好在一个班级,一个班级可以有许多学生 让我们也假设这些是大类。也就是说,每个班有1000名学生 类实体看起来像: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。。。等
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的更改,以便在需要时再次运行该请求