用于一对多的 iOS Core 数据谓词

Posted

技术标签:

【中文标题】用于一对多的 iOS Core 数据谓词【英文标题】:iOS Core data predicate for one-to-many 【发布时间】:2014-09-02 11:13:59 【问题描述】:

如图所示,我有两个实体。我需要获取一个特定的约会和所有未删除与会者的相关与会者(hasDeleted != 1)。我尝试过不同的谓词格式。以下是我尝试过的两个主要谓词,但无法使这些谓词中的任何一个起作用。你能帮我解决这个问题吗?

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"objectName = %@ AND objectId = %i AND SUBQUERY(attendees, $x, $x.hasDeleted != 1).@count != 0", [self.userDefaults stringForKey:OBJECT_NAME], [[self.userDefaults objectForKey:OBJECT_ID] intValue]];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"objectName = %@ AND objectId = %i AND (ANY attendees.hasDeleted != 1)", [self.userDefaults stringForKey:OBJECT_NAME], [[self.userDefaults objectForKey:OBJECT_ID] intValue]];

约会列表表格视图

可以查看与会者详细信息的详细约会视图。

获取结果控制器代码:

- (NSFetchedResultsController *)fetchedResultsController

    if (_fetchedResultsController != nil) 
        return _fetchedResultsController;
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Attendee" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"uuid" ascending:NO];
    NSArray *sortDescriptors = @[sortDescriptor];

    [fetchRequest setSortDescriptors:sortDescriptors];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"appointment.objectName = %@ AND appointment.objectId = %i AND hasDeleted != 1", [self.userDefaults stringForKey:OBJECT_NAME], [[self.userDefaults objectForKey:OBJECT_ID] intValue]];

    [fetchRequest setPredicate:predicate];

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

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) 
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    
    return _fetchedResultsController;

【问题讨论】:

您是否有任何错误记录到控制台? “objectId = %i”可以改成“objectId = %@”并传递一个NSNumber对象(那么就不需要将它转换为int)。您不需要子查询,第二个应该可以工作。 您是否尝试过“一个接一个”地使用您的谓词?我的意思是,划分所有的和/或/子查询,看看是否能得到你想要的。然后一点一点的组合起来。 @thom_ek 没有错误。它只是返回所有与会者而不过滤第二个。 @thom_ek 还有什么想法吗? @Larme 你是说分别尝试 AND、OR、SUBQUERY 吗? 【参考方案1】:

获取请求总是从托管对象上下文返回对象。你不能 获取“修改后的对象”,例如具有修改关系的约会对象 “参加者”,仅包含具有特定属性的参加者。

您可以改为获取未删除的 Attendee 对象 这与给定的约会有关。 为参加者实体创建一个获取请求并使用谓词

[NSPredicate predicateWithFormat:@"appointment.objectName = %@ AND appointment.objectId = %i AND hasDeleted != 1", [self.userDefaults stringForKey:OBJECT_NAME], [[self.userDefaults objectForKey:OBJECT_ID] intValue]]

更新 根据新信息:在您的第一个视图控制器中,您使用 Appointment 实体的获取请求的获取结果控制器。 如果您只想显示有任何与会者尚未取消的约会 然后添加谓词

[NSPredicate predicateWithFormat:"ANY attendees.hasDeleted != 1"]

到这个获取请求。

当用户点击约会时,您将选择的约会传递到下一个视图 控制器。要显示此约会的与会者,请使用获取的结果 控制器对 Attendee 实体有一个获取请求,并添加谓词

[NSPredicate predicateWithFormat:@"appointment = %@ AND hasDeleted != 1", selectedAppointment]

【讨论】:

我们在这里修改任何对象吗?我们只是限制“参加者”。您的解决方案有效。但是这会返回参加者对象,其中包含对每个参加者的重复约会引用。 @Chinthaka:没有对象被修改。我不完全理解你的最后一句话。据我了解您的问题,所有获取的参加者对象都应与 same 约会(在谓词中指定)相关。 你是说我必须先获取约会,然后为与会者单独获取?有没有办法一次性做到这一点?因为我使用 NSFetchedResultsController 将这些约会填充到 tableview。 @Chinthaka:不,你只是获取与会者,attendee.appointment 是 Appointment 对象。 这里有一个问题。你有什么方法可以从NSFetchedResultsController 获取约会号码。这是给numberOfRowsInSection

以上是关于用于一对多的 iOS Core 数据谓词的主要内容,如果未能解决你的问题,请参考以下文章

swift Core Data谓词过滤给定父级的所有子数据

EF Core中通过Fluent API配置一对多关系

谓词匹配一对多关系核心数据

可可 iphone 核心数据谓词一对多 fetchrequest

不搜索一对多核心数据关系

具有一对多关系的复杂核心数据谓词