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模为Person
和Appointment
实体的反向关系)
我想把所有人的过去任命计算在内。
在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];