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

时间:2014-12-05 09:27:46

标签: ios objective-c core-data

在我的CoreData模型中,我有一个使用中间实体建模的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

(这两种关系也被建模为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的count-function表达式,方法如下:

 // 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日志后,核心数据似乎执行了正确的声明:

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>";
}

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

我在这里做错了吗?

还是有另一种方法可以实现这个目标吗?

2 个答案:

答案 0 :(得分:2)

在我看来,这就像CoreData中的一个错误,但经过一些实验,我认为你可以通过修改计数表达式来实现你想要的,计算你{{1>的属性实体,而不是计算Person2Appointment关系(计数应该是相同的,因为关系是-1,除非你有空值?):

Appointment

如果您确实需要担心空值,可以使用:

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

答案 1 :(得分:0)

我只是在这里展开它,但你可能会发现尝试子查询的运气

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