核心数据 - 在不触发错误的情况下获取对多关系的 objectID

Posted

技术标签:

【中文标题】核心数据 - 在不触发错误的情况下获取对多关系的 objectID【英文标题】:Core Data - Get objectIDs of to-many relationship without firing a fault 【发布时间】:2011-10-01 09:50:54 【问题描述】:

我有一个具有一对多关系的实体。从我的实体中获取对象的子集后,我想获取关系对象的 ManagedObjectID - 而不会触发错误。这可能吗?我从文档中的理解是,在错误上调用 objectID 不会导致它触发,但是当我尝试以下行时,仍然会为每个对象的关系触发一个错误:

[word.articles valueForKeyPath:@"objectID"];

我也尝试了以下方法,结果相同:

[word valueForKeyPath:@"articles.objectID"];

我现在也尝试了以下方法,但不幸的是文章故障仍然存在:

for (Article *article in word.articles) 

   [articleIDs addObject:article.objectID];

任何帮助将不胜感激!

【问题讨论】:

没有错误发生——所发生的只是一个错误被触发,这意味着去商店旅行,并且处理时间显着增加 【参考方案1】:

这在 ios 8.3 中成为可能

/* returns an array of objectIDs for the contents of a relationship. 
   to-one relationships will return an NSArray with a single 
   NSManagedObjectID.  Optional relationships may return an empty 
   NSArray. 
   The objectIDs will be returned in an NSArray regardless of the type 
   of the relationship.  */
- (NSArray<NSManagedObjectID *> *)objectIDsForRelationshipNamed:(NSString *)key NS_AVAILABLE(10_11,8_3);

它会去商店一趟以获取所有 ID。

【讨论】:

【参考方案2】:

您需要做的是使用这样的谓词为 Articles 实体创建一个 NSFetchRequest(其中 'word' 是一个单词管理对象):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(ANY words == %@)", word];

设置 resultType = NSManagedObjectIDResultType 正如 Ashley 在他的回答中所说的那样。

然后,获取请求将返回包含指定单词的文章的文章 ObjectID 集合。

OR:如果您想通过单词的文本查找而不是首先将其作为托管对象获取,则使用这样的谓词。 (其中 'wordText' 是一个 NSString 并假设 - 'text' 是 Word 实体的一个字段)

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(ANY words.text == %@)", wordText];

【讨论】:

不幸的是,这不是一个选项,因为它要求所有文章的所有单词都与正在搜索的单词匹配。该数据库包含数千篇文章,每篇文章包含数百个单词。 我假设“运行循环”正在尝试查找包含给定单词的所有文章。添加新文章时,文章中的每个单词都被添加为“单词”实体并建立关系。这是与数据库有关的相当典型的事情。如果不是这种情况,那么 Run Loop 需要更详细地解释他想要实现的目标。 @Robin - 这正是我想要做的。 @RunLoop 好。那么,我回答了你的问题了吗? 不,但在您的评论中,您肯定了我关于为什么您的答案不是一个选项的评论。【参考方案3】:

我认为您可能必须使用 NSFetchRequest,用于实体文章和设置

request.resultType = NSManagedObjectIDResultType

如果问题是 多个 故障触发(因此多个 SQL 请求),那么提取请求如何最初提取 所有 您需要的文章,这意味着只有一个 SQL 请求是造出来的?

【讨论】:

问题是我不知道要在请求中包含哪些文章 - 要知道我必须查询 word.articles,这会引发错误并使我们回到我的问题,如上所述【参考方案4】:

一种可能性是执行预取,以便在初始提取期间提取您的关系对象,因此以后不会导致错误。

查看NSFetchRequest 类中的relationshipKeyPathsForPrefetching 属性。下面是一个示例,其中request 返回一个包含articles 属性的Word 对象数组:

[request setRelationshipKeyPathsForPrefetching:@[@"articles"]];

【讨论】:

以上是关于核心数据 - 在不触发错误的情况下获取对多关系的 objectID的主要内容,如果未能解决你的问题,请参考以下文章

如何在不复制目标 NSManagedObject 的情况下将目标 NSManagedObject 添加到另一个具有反向多对多核心数据关系的对象?

在不获取现有对象的情况下创建核心数据关系

如何在不破坏范式的情况下为多对多关系构建连接表

如何在不更新具有多对多关系的子实体的情况下保留父实体?

Django - 使用表单集在不通过表的情况下建立 2 个模型之间的多对多关系

PHP在不使用数组的情况下触发AJAX错误代码