objective-c - 跨一对一关系的核心数据获取请求谓词过滤

标签 objective-c ios core-data

我有以下模型图:

                  +-----------+     +-----------+
                  | Container |     |   Group   |
                  +-----------+     +-----------+
                  |  groups   |<-->>| container |
                  +-----------+     +-----------+
                        ^                 ^
                        |                 |
+-----------+     +-----------+     +-----------+     +---------+
|   Owner   |     |  ToyBox   |     |  ToyType  |     |  Item   |
+-----------+     +-----------+     +-----------+     +---------+
|  toyBox   |<--->|   owner   |     |   items   |<-->>| toyType |
+-----------+     +-----------+     +-----------+     +---------+

在 UITableView 中,我要显示一个项目列表。在这种情况下,我只想显示属于特定所有者的项目。为此,我将使用 NSFetchedResultsController 来显示项目。这意味着我需要创建一个带有适当 NSPredicate 的 NSFetchRequest 以提供给 NSFetchedResultsController。

由于父实体,尝试使用键路径谓词会导致异常。这似乎是 Apple 错误或决定不支持。雷达已备案。此外,我不希望扁平化实体。

因此,我尝试使用 SUBQUERY() 执行以下操作:

NSFetchRequest *itemsFetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Item"];
NSPredicate *itemsPredicate = [NSPredicate predicateWithFormat:@"SUBQUERY(toyItem, $g, SUBQUERY($g.container, $c, SUBQUERY($c.owner, $o, $o = %@).@count > 0).@count > 0).@count > 0", ownerObject];

这会导致以下异常:

Can't have a non-relationship collection element in a subquerySUBQUERY($c.owner, $o, $o == <MLMOOwner: ...

我意识到,因为 Owner 和 ToyBox 之间的关系是一对一的,所以没有返回集合,这就是问题所在。所以我的问题是:

1) 有没有办法强制返回子查询中一对一关系的集合?
2) 如果没有,是否有另一种方法可以为获取请求创建此谓词?

最佳答案

看起来做你想做的事应该简单得多。如果您想要具有给定所有者的所有项目,请从所有者开始并使用关键路径获取关联的项目。你不需要谓词。如果你有 10 jar 花生,你想取回 jar 2 中的花生,你不会从所有花生的集合开始,然后根据它们的 jar 过滤它们,对吧?您首先得到 jar 2,然后查看其中包含的花生。所以这样做:

NSSet *groups = [ownerObject valueForKeyPath:@"toyBox.groups"];

这为您提供了 ownerObject 拥有的所有组。您不能只使用单个键路径获取所有项目,因为 Group 实体没有 items 属性。通过为 Group 提供一个 items 访问器,您可以让自己的生活更轻松,即使它只返回一个空集。那会让你这样做:

NSSet *items = [ownerObject valueForKeyPath:@"toyBox.groups.items"];

如果您不想将 items 属性添加到 Group,则必须从第一个开始过滤集合 groups例如,只挑选出那些是 ToyType 对象的对象。然后,您可以在该集合上使用键路径 @"items" 来获取您想要的项目列表。

你必须小心处理实体继承。您刚刚看到它如何使抓取变得更加复杂。它还对数据的存储方式有影响,即 all instances of sub-entities are stored in the same table .因此,如果您有十几个从 Group 派生的实体(例如 ToyType),所有这些实体的所有实例都存储在一起。

关于objective-c - 跨一对一关系的核心数据获取请求谓词过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12133396/

相关文章:

iphone - 循环声音在循环结束时有咔嗒声

objective-c - 尝试制作自定义 TabBar。在 iPhone 3GS 中使用 viewController 转换会崩溃(但在 iPhone 4 中不会)

ios - 如何加速或优化 iOS 的 SQLite 查询?

ios - 如何知道字符串是否在 iOS 中进行了 url 编码?

iphone - 我们可以使用核心数据来存储房地产吗?

ios - iPhone : Multiple touches on a UIButton are not recognized

iphone - 如何获取我在iphone中向谁发送电子邮件的数据

ios - 在 iOS 11 Swift 4 上应用渐变后,UINavigationBar 标题和按钮消失

ios - Core Data addPersistentStoreWithType 返回 nil,但错误也是 nil

ios - 从过滤关系为空的核心数据中获取对象