CoreData以另一个关系(m2n)获取关系和组的计数请求

在我的CoreData模型中,我有一个使用中间实体build模的n2n关系:

Person [1<--] Person2Appointment [-->1] Appointment 

Person2Appointment实体如下所示:

 @interface Person2Appointment : NSManagedObject // attributes @property (nonatomic, retain) NSNumber * participationState; // relations @property (nonatomic, retain) Person * person; @property (nonatomic, retain) Appointment * appointment; ... @end 

(这两个关系也被build模为PersonAppointment实体的反向关系)

我想把所有人的过去任命计算在内。

在SQL中,它看起来像:

 select count(fk_appointment), fk_person from person2appointment t0 left join appointment t1 on t0.fk_appointment = t1.pk where t1.date < ... group by fk_person; 

我试着用我的fetch-request使用一个计数函数expression式,如下所示:

  // create a fetch request for the Person2Appointment entity (category method) NSFetchRequest* fetch = [Person2Appointment fetchRequest]; fetch.resultType = NSDictionaryResultType; // count appointments NSExpression* countTarget = [NSExpression expressionForKeyPath: @"appointment"]; NSExpression* countExp = [NSExpression expressionForFunction:@"count:" arguments: @[countTarget]]; NSExpressionDescription* countDesc = [[NSExpressionDescription alloc]init]; countDesc.name=@"count"; countDesc.expression = countExp; countDesc.expressionResultType = NSDecimalAttributeType; fetch.propertiesToFetch = @["person", countDesc]; fetch.propertiesToGroupBy = ["person"]; fetch.predicate = ...; 

打开SQL日志logging似乎核心数据执行正确的声明:

 SELECT t0.ZPERSON, COUNT( t0.ZAPPOINTMENT) FROM ZPERSON2APPOINTMENT t0 JOIN ZAPPOINTMENT t1 ON t0.ZAPPOINTMENT = t1.Z_PK WHERE t1.ZSTARTDATE > ? GROUP BY t0.ZPERSON 

但是结果数组中的字典不包含数字计数,而是包含约会实体:

 Printing description of d: { count = "0xd0000000000c0018 <x-coredata://BABCBD2E-05AB-4AA5-AC2B-2777916E4EDF/Appointment/p3>"; person = "0xd0000000000c0016 <x-coredata://BABCBD2E-05AB-4AA5-AC2B-2777916E4EDF/Person/p3>"; } 

这是核心数据中的错误吗?

我在这里做错了什么?

或者有另一种方法来实现这一目标?

这看起来像一个CoreData中的错误,但经过一些实验,我认为你可以通过修改计数expression式来实现你想要的,来计算你的Person2Appointment实体的属性 ,而不是计数Appointment关系(计数应该是一样的,因为关系是一对一的,除非你有空值?):

 NSExpression* countTarget = [NSExpression expressionForKeyPath: @"participationState"]; NSExpression* countExp = [NSExpression expressionForFunction:@"count:" arguments: @[countTarget]]; 

如果你有空值担心,你可以使用:

 NSExpression *countTarget = [NSExpression expressionForEvaluatedObject]; 

我只是在这里,但你可能会发现尝试一个子查询一些运气

 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(durationMinutes, $a, $a.date < %@)", someDate); NSInteger count = [managedObjectContext countForEntityForName:@"Person2Appointment" predicate:predicate error:&error];