核心数据获取记录按关系分组?

屏幕截图添加 我有两个名为ExpensesExpensesCategory的实体, ExpensesCategoryCategoryExpenses有以下属性 – name-expenseCategory,Destination – ExpensesCategory,inverse-expense。 ExpensesCategory有一个名为expenseCategory的字符串类型属性, Expenses有一个名为amount的属性。 现在我想获取费用由amountCategory分组的费用。 这是我的代码

 NSSortDescriptor *sortTitle =[NSSortDescriptor sortDescriptorWithKey:@"addedTimestamp" ascending:YES]; NSArray *sortDescriptors = [NSArray arrayWithObjects:sortTitle, nil]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Expense" inManagedObjectContext:context]; NSPredicate *predicate; predicate =[NSPredicate predicateWithFormat:@"(addedTimestamp = %@)",currentDate, endDate]; NSAttributeDescription* amtDescription = [entity.attributesByName objectForKey:@"amount"]; NSRelationshipDescription* nameDesc = [entity.relationshipsByName objectForKey:@"expenseCategory"]; NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"amount"]; NSExpression *countExpression = [NSExpression expressionForFunction: @"sum:" arguments: [NSArray arrayWithObject:keyPathExpression]]; NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName: @"Sum"]; [expressionDescription setExpression: countExpression]; [expressionDescription setExpressionResultType: NSDecimalAttributeType]; [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:amtDescription, expressionDescription, nameDesc, nil]]; [fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObject:nameDesc]]; [fetchRequest setResultType:NSDictionaryResultType]; [fetchRequest setEntity:entity]; [fetchRequest setPredicate:predicate]; [fetchRequest setSortDescriptors:sortDescriptors]; [context executeFetchRequest:fetchRequest error:&error]; 

但是当我运行Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attribute/relationship description names passed to setPropertiesToFetch: must match name on fetch entity得到Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attribute/relationship description names passed to setPropertiesToFetch: must match name on fetch entity

任何帮助,将不胜感激。

以下是您的问题的答案。

 NSEntityDescription *entity = [NSEntityDescription entityForName:@"ExpenseCategory" inManagedObjectContext:context]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; [fetchRequest setEntity:entity]; NSError *error; fetchRequest.predicate =[NSPredicate predicateWithFormat:@"(addedTimestamp <= %@) AND (addedTimestamp >= %@)",currentDate, endDate]; NSSortDescriptor *sortTitle =[NSSortDescriptor sortDescriptorWithKey:@"addedTimestamp" ascending:YES]; fetchRequest.sortDescriptors = [NSArray arrayWithObjects:sortTitle, nil]; NSExpressionDescription *ex = [[NSExpressionDescription alloc] init]; [ex setExpression:[NSExpression expressionWithFormat:@"@sum.expense.amount"]]; [ex setName:@"Sum"]; [ex setExpressionResultType:NSDecimalAttributeType]; [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"expenseCategory", ex, nil]]; [fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObject:@"expenseCategory"]]; [fetchRequest setResultType:NSDictionaryResultType ]; // Execute the fetch. NSArray *matchingObjects = [context executeFetchRequest:fetchRequest error:&error]; if ([matchingObjects lastObject]) { for (id expenseCategory in matchingObjects) { NSLog(@"%@", expenseCategory); } } 

如果您想要按Expense addedTime而不是ExpenseCategory addedTime进行过滤,则将谓词更改为:

 fetchRequest.predicate =[NSPredicate predicateWithFormat:@"(expense.addedTimestamp <= %@) AND (expense.addedTimestamp >= %@)",currentDate, endDate]; 

在回答另一个问题的同时,我发现了这个问题中突出显示的特定错误的原因(“传递给setPropertiesToFetch的属性/关系描述名称:必须与获取实体上的名称匹配”)。 我正在添加这个答案,以帮助那些寻求解决该错误的人。

出现此错误的原因是fetchRequest的propertiesToFetch正在fetchRequest的entity之前设置。 更改代码的顺序应解决问题:

  [fetchRequest setEntity:entity]; [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:amtDescription, expressionDescription, nameDesc, nil]]; [fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObject:nameDesc]]; [fetchRequest setResultType:NSDictionaryResultType]; 

Apple文档很清楚, propertiesToFetch包含的属性和关系必须与属性名称匹配:

“属性或关系描述的名称必须与获取请求的实体上的描述名称相匹配。”

但是我花了很长时间才意识到一旦你设置了propertiesToFetch (而不是执行fetch)就进行了这个测试,因此需要先设置entity

你正在传递|expressionDescription| ,这是一个NSExpressionDescription ,to setPropertiesToFetch: ; setPropertiesToFetch:接受只有NSPropertyDescriptions的数组,因此抛出exception。

setPropertiesToGroupBy:允许使用NSExpressionDescriptionsNSPropertyDescriptions setPropertiesToGroupBy:但是。

你应该看一下预取技术。 在这个url中,您可以找到EmployeeDepartment之间的示例。

希望有所帮助!