繁体   English   中英

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

[英]Core data fetch records Group by relationship?

屏幕截图已添加 我命名的两个实体ExpensesExpensesCategoryExpenses有关系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:中允许同时使用NSExpressionDescriptionsNSPropertyDescriptions

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

希望有帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM