使用 NSPredicate 的特定对象内的核心数据 NSFetchRequest

Posted

技术标签:

【中文标题】使用 NSPredicate 的特定对象内的核心数据 NSFetchRequest【英文标题】:Core Data NSFetchRequest within specific object using NSPredicate 【发布时间】:2016-02-23 13:25:03 【问题描述】:

我有一个核心数据实体,“实体 1”,它与另一个实体“实体 2”之间存在一对多关系,我们称其为“实体关系”。

我希望能够执行 NSFetchRequest 以与 NSFetchResultsController 一起使用,以返回特定“实体 1”对象的“实体 2”对象列表。

我将“实体 1”作为它自己的变量存储出来,但我似乎找不到设置 NSPredicate 以返回对象的正确方法:

这是我的代码:

 NSFetchedResultsController *fetchedEvents;
    NSFetchRequest *fetchRequest;
    NSError *error = nil;

    fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Entity2"];
    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"Entity2 IN self = %@",entity1Object]];
    [fetchRequest setSortDescriptors:@[]];// no sort descriptors
    fetchedEvents = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:theManagedObjectContext sectionNameKeyPath:nil cacheName:nil];
    [fetchedEvents performFetch:&error];

    if (error) 
        NSLog(@"Unable to perform fetch.");
        NSLog(@"%@, %@", error, error.localizedDescription);
    
    return fetchedEvents;

这会崩溃并出现以下错误:

** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "NSMDEvents IN self = %@"'

我做错了吗?或者这是返回具有关系的实体的错误方法?

【问题讨论】:

【参考方案1】:

由于您有entity1Object 和定义的关系,您可以直接从那里检索Entity2 对象

NSSet *entity2Objects = [entity1Object valueForKey:@"entityRelationship"];

不需要额外的提取。


但是,如果您确实需要获取,请定义反向关系并使用具有唯一值的属性。

例如让我们假设entity1clubsentity2 是他们的members 并且您想要让特定俱乐部的所有成员使用这个谓词:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Member"];    
[NSPredicate predicateWithFormat:@"club.name == %@", currentClub.name];

谓词中的文字club是反向关系对象。

或者翻译成你的例子

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Entity2"];    
[NSPredicate predicateWithFormat:@"entity1.property == %@", entity1Object.property];

【讨论】:

嗨 Vadian,感谢您的帮助,您肯定为我指明了正确的方向,我最终使用我的回答帖子中的代码使其工作,但如果您认为这种方法似乎不正确,请告诉我. 如果它有效,那很好。检查实体对象或实体的特定属性并不重要。顺便说一句:你的命名Entity<ordinalnumber>很抽象,不是很具描述性,也很难想象。 是的,我应该在那里使用一些更好的命名约定。感谢您的意见。【参考方案2】:

尝试建议的代码(感谢 vadian)一直导致我的应用程序崩溃,并出现各种关于键不存在等的错误,结果证明这是关系问题。

“Entity2”继承自另一个实体(在 Data Model Inspector 中设置了其父 Entity 字段)“Entity 0”。然而,“Entity1”之间的关系是它自己和“Entity0”而不是“Entity2”之间的关系。

因此,在对核心数据模型“Entity2”进行重构之后,在其自身和“Entity1”之间添加了一个关系(我们称之为“EntityEvents”)。现在使用以下代码,我能够从当前对象中选择特定事件:

 NSFetchedResultsController *fetchedEvents;
    NSFetchRequest *fetchRequest;
    NSError *error = nil;

    fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Entity2"];
    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"EntityEvents == %@",Entity1]];
    [fetchRequest setSortDescriptors:@[]];// no sort descriptors
    fetchedEvents = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:theManagedObjectContext sectionNameKeyPath:nil cacheName:nil];
    [fetchedEvents performFetch:&error];

    if (error) 
        NSLog(@"Unable to perform fetch.");
        NSLog(@"%@, %@", error, error.localizedDescription);
    

    return fetchedEvents;

【讨论】:

以上是关于使用 NSPredicate 的特定对象内的核心数据 NSFetchRequest的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSPredicate 获取核心数据对象数组?

带有核心数据对象的 NSPredicate

通过对象的枚举属性使用 NSPredicate 获取核心数据托管对象的问题

使用核心数据在 NSPredicate 中调用对象的方法

使用 NSPredicate 过滤核心数据中的对象

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