[英]Core data fetch records Group by relationship?
我命名的两个实体Expenses
和ExpensesCategory
的Expenses
有关系CategoryExpenses
具有以下属性-名称expenseCategory,目的地- ExpensesCategory,逆-费用。 ExpensesCategory
具有字符串类型的expenseCategory属性, Expenses
具有名称为amount的属性。 现在,我想获取按费用类别分组的费用senseCategory。 这是我的代码
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 <= %@) AND (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 createdTime而不是ExpenseCategory createdTime进行过滤,则将谓词更改为:
fetchRequest.predicate =[NSPredicate predicateWithFormat:@"(expense.addedTimestamp <= %@) AND (expense.addedTimestamp >= %@)",currentDate, endDate];
在回答另一个问题时,我发现了该问题中突出显示的特定错误的原因(“传递给setPropertiesToFetch的属性/关系描述名称:必须与获取实体上的名称匹配”)。 我正在添加此答案,以帮助那些寻求针对该错误的解决方案的人。
发生此错误的原因是,在fetchRequest的entity
之前设置了fetchRequest的propertiesToFetch
。 更改代码顺序应该可以解决问题:
[fetchRequest setEntity:entity];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:amtDescription, expressionDescription, nameDesc, nil]];
[fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObject:nameDesc]];
[fetchRequest setResultType:NSDictionaryResultType];
Apple文档明确指出, propertiesToFetch
包含的属性和关系必须与属性名称匹配:
“属性或关系描述的名称必须与获取请求的实体上的描述名称匹配。”
但是,我花了很长时间才意识到,只要您设置propertiesToFetch
(而不是在执行获取时)就进行了此测试,因此需要首先设置entity
。
您正在通过|expressionDescription|
,它是一个NSExpressionDescription
,用于setPropertiesToFetch:
NSExpressionDescription
setPropertiesToFetch:
接受仅NSPropertyDescriptions
数组,因此会引发异常。
但是, setPropertiesToGroupBy:
中允许同时使用NSExpressionDescriptions
和NSPropertyDescriptions
。
您应该看一下预取技术。 在此url中,您可以找到Employee
和Department
之间的示例。
希望有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.