iPhone如何使用NSPredicate按父实体过滤Core Data?

Posted

技术标签:

【中文标题】iPhone如何使用NSPredicate按父实体过滤Core Data?【英文标题】:iPhone how to use NSPredicate to filter Core Data by the parent entity? 【发布时间】:2012-04-27 18:08:26 【问题描述】:

我的核心数据是这样定义的: 用户有很多事件; 事件具有单一的用户关系;

用户和事件都是核心数据实体。用户实体通过情节提要 segue 传入。

我正在尝试配置 NSPredicate 以仅使用该特定用户的事件填充该用户的详细 UITableView。

到目前为止我已经尝试过

//does not work
 NSPredicate* onlyThisUserPredicate = [NSPredicate predicateWithFormat:@"user == %@",self.appUser];

//does not work
 NSPredicate* onlyThisUserPredicate = [NSPredicate predicateWithFormat:@"SELF.user == %@",self.appUser];

比较事件并仅返回用户对象等于指定用户对象的事件的正确语法是什么?

更新:

我正在尝试使用这种获取的结果控制器向用户添加事件:

-(NSFetchedResultsController*)fetchedResultsController

    if (__fetchedResultsController != nil) 
        return __fetchedResultsController;
    

    // Set up the fetched results controller.
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:[Event managedObjectContext]];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

//I need to configure this user
    NSPredicate* onlyThisUserPredicate = [NSPredicate predicateWithFormat:@"user = %@",self.appUser];


    // The first sort key must match the section name key path key if present, otherwise the initial dataset would be messed up: rows in incorrect sections

    NSString* firstSortKey = @"createDate";
    NSSortDescriptor *firstSortDescriptor = [[NSSortDescriptor alloc] initWithKey:firstSortKey ascending:YES];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:firstSortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];
    [fetchRequest setPredicate:onlyThisUserPredicate];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[Event managedObjectContext] sectionNameKeyPath:nil cacheName:@"Events"];
    self.fetchedResultsController = aFetchedResultsController;
    aFetchedResultsController.delegate = self;

    //    [aFetchedResultsController release];
    [sortDescriptors release];
    [fetchRequest release];

    NSError *error = nil;
    if (![__fetchedResultsController performFetch:&error]) 
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        //      abort();
    


    return __fetchedResultsController;

谢谢!

【问题讨论】:

你得到了什么结果?任何事物?您能否分享您的 fetch 请求的完整定义? 出于某种原因,我得到了任何用户的 3 个结果。如果我使用 user.events.count 手动检查用户的事件数,我会得到 1 到 4 之间。这告诉我,我的谓词正在返回一些东西,但它不正确。 【参考方案1】:

好的,我能想到有几件事可能会导致这种行为。

首先,您是否在此函数中验证了 self.appUser 的值?设置是否符合您的预期?

其次,您是否确保您的标头都是最新的并包含在此文件中?有时,当我的标头未与 coredata 模型保持同步时,我会遇到奇怪的行为。

【讨论】:

【参考方案2】:

所以这个谓词是针对用户实体的,对吗?如果是这样,您是否尝试过:

NSPredicate* onlyThisUserPredicate = [NSPredicate predicateWithFormat:@"SELF == %@",self.appUser];

然后您可以通过以下方式访问您的活动:

[self.appUser events];

【讨论】:

这个谓词是获取一个有用户关系的事件实体列表,并且该关系的值等于当前选中的用户。【参考方案3】:

如果您已经从 Core Data 存储中检索到“用户”,那么您应该能够通过遵循该关系来访问其事件——无需执行单独的获取请求:

NSSet *events = self.appUser.events;

另一方面,如果self.appUser 不是托管对象,那么在谓词中使用== 运算符可能就是问题所在。所以让我假设self.appUser 只是一个包含用户名的字符串,而不是数据存储中的用户对象。然后你会在你的谓词中使用'like'运算符:

NSPredicate* onlyThisUserPredicate = [NSPredicate predicateWithFormat:@"user like %@",self.appUser];

另外,请确保您在提取请求中指定了正确的实体。对于您所描述的内容,您应该使用事件实体的实体描述进行提取。

【讨论】:

不幸的是,它们都是核心数据对象。我用完整的获取请求定义澄清了这个问题

以上是关于iPhone如何使用NSPredicate按父实体过滤Core Data?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NSFetchedRequest 或 NSPredicate 从实体中选择所有行?

如何使用 NSFetchedResultsController 设置过滤指定组中项目的 NSPredicate

iOS核心数据如何使用NSPredicate根据一对多的子属性查找父对象?

iPhone NSPredicate 如何创建一个检查属性是不是有值的谓词?

如何将 NSManagedObject 传递给 NSPredicate 以及如何保存一对多的实体

如何设置 NSPredicate 来检查关系的属性?