添加setRelationshipKeyPathsForPrefetching后仍然显示获取一对多关系错误

时间:2014-06-04 04:49:07

标签: core-data relationship fetch predicate fault

假设我的数据模型有两个实体:Department和Person。部门与Person有一个叫做“departmentToPerson”的多对多关系。人与部门有一对一的称为'personToDepartment'的关系。

我想填充属于所选部门的一系列人员。为了选择部门,我创建了一个UILabel,显示从弹出式tableview中选择的departmentName。当我运行应用程序时,日志显示:

  

personToDepartment.departmentName ==(实体:   部门; id:0x8cc1920    ;   数据:{       departmentName =营销;       departmentToPerson =“”;

我已经阅读了故障的目的并实现了setRelationshipKeyPathsForPrefetching,但我仍然得到了错误。我会放弃免责声明我是新手,可能会遗漏一些明显的东西。当我删除谓词时,我的表视图会填充所有personName。这是代码:

- (NSFetchedResultsController *)fetchedResultsController {

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                entityForName:@"Person" inManagedObjectContext:_managedObjectContext];
    [fetchRequest setEntity:entity];


    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"personToDepartment.departmentName = %@", selectedDepartment];
    NSLog(@"predicate is: %@",predicate);

    [fetchRequest setPredicate:predicate];

    [fetchRequest setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects: @"departmentToPerson", nil]];

fetchRequest.returnsObjectsAsFaults = NO;

    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                    initWithKey:@"personName" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];


    [fetchRequest setFetchBatchSize:20];


    NSFetchedResultsController *theFetchedResultsController =
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
            managedObjectContext:_managedObjectContext sectionNameKeyPath:nil
                cacheName:nil];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;

}

再一次,我从UILabel中选择一个新的部门,日志显示selectedDepartment,但是然后说明关系错误并且没有填充表。

提前感谢您的帮助!

更新于9月9日

我也发现这有效:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"personToDepartment = %@", selectedDepartment];

1 个答案:

答案 0 :(得分:0)

我也是CoreData的新手,但在我看来,谓词是错误的。根据日志记录,您要将personToDepartment.departmentName与部门对象进行比较。谓词应该如下: NSPredicate *predicate = [NSPredicate predicateWithFormat:@"personToDepartment.departmentName = %@", selectedDepartment.departmentName];

但还有更好的方法。 selectedDepartment.departmentToPerson将返回一个NSSet,其中包含属于该部门的所有人员(如果先前已设置关系)。但警告,如果您尝试NSLog(@"%@", selectedDepartment.departmentToPerson)可能会导致" 关系错误",因为CoreData在您解决之前不会进行提取NSSet中的特定对象或通过它枚举。但是,例如NSLog(@"%d", selectedDepartment.departmentToPerson.count)将强制CoreData进行提取,并且您将看到部门中的人数。

更新: 在创建人物对象时,NSSet可能是因为您没有设置关系。部门与人之间的反向对多关系将自动设置。

- (id)insertNewPerson:(NSDictionary *)personInfo inDepartment:(Department*)departmentObject 
{
    Person *personObject = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
    personObject.name = personInfo.name;
    personObject.departmentName = departmentObject.name;
    ...
    personObject.personToDepartment = departmentObject;   //this is RELATIONSHIP, if set, then you can access all persons from specific department by doing: departmentObject.departmentToPerson
}