具有不同值和表达式的NSFetchRequest

时间:2011-07-13 15:38:30

标签: cocoa core-data

我必须为我的iPhone App创建一个NSFetchRequest,它返回与以下SQL语句相同的结果:

SELECT week
      , year
      , SUM(duration) AS totalDuration
FROM myTable
GROUP BY year
      , week

我试图用以下代码解决这个问题:

NSExpression * durationExpression = [NSExpression expressionForFunction:@"sum:" arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:@"duration"]]];
NSExpressionDescription * durationExpressionDescription = [[[NSExpressionDescription alloc] init] autorelease];
[durationExpressionDescription setExpression:durationExpression];
[durationExpressionDescription setExpressionResultType:NSDoubleAttributeType];
[durationExpressionDescription setName:@"totalDuration"];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:managedObjectContext];
NSArray *propertiesToFetch = [[NSArray alloc] initWithObjects:@"year", @"week", durationExpressionDescription, nil];

[fetchRequest setEntity:entity];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setPropertiesToFetch:propertiesToFetch];

但是这会将所有结果分组到一行。任何提示如何解决?

编辑:源表包含以下数据:

year | month | duration
2011 |     7 | 10
2011 |     7 | 15
2011 |     6 | 15
2011 |     5 | 10

SQL语句返回我想要实现的正确结果:

year | month | duration
2011 |     7 | 25
2011 |     6 | 15
2011 |     5 | 10

NSFetchRequest返回:

year | month | duration
2011 |     7 | 50

1 个答案:

答案 0 :(得分:-1)

非常确定您的单次返回是由NSExpression触发的,它只返回一个值。否则,你会得到一系列这样的词典:

year | month | duration
2011 |     7 | 50
2011 |     6 | 50
2011 |     5 | 50

...实际上并不反映数据的状态。

表达式配置为返回给定的duration的每个实例中的所有MyEntity值的总和。由于您没有获取谓词,因此将为上下文可用的每个现有MyEntity实例提供它。然而,它只能返回单个值,这意味着在按属性获取时使用单个字典。

对此最好的解决方案是仅为表达式创建单独的提取,因为它实际上与提取的其他值无关,即求和值与任何特定年份或月份值无关。在任何情况下,简单的提取运行得更快,因此将表达式分离出来将为您提供整体速度提升,即使您有两次提取而不是一次提取。

我会提醒您避免像使用SQL那样尝试使用Core Data。将Core Data视为SQL包装器是一个重大错误。核心数据不是SQL。实体不是表格。对象不是行。属性不是列。关系不是联接。核心数据是一个对象图管理系统,可能会或可能不会持久保存对象图,并且可能会或可能不会使用远远落后的SQL来执行此操作。很少有人直接从SQL转换为核心数据。