0

我有以下模型图:

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

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

由于父实体,尝试使用 keypath 谓词会导致异常。这似乎是 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)如果没有,还有另一种方法可以为获取请求创建这个谓词吗?

4

1 回答 1

2

似乎做你想做的事情应该简单得多。如果您想要拥有给定所有者的所有项目,请从所有者开始并使用密钥路径来获取关联的项目。你不需要谓词。如果你有 10 罐花生,你想取回罐子 2 中的花生,你不会从所有花生的集合开始,然后根据它们的罐子过滤它们,对吗?您首先得到 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"集合上的密钥路径来获取您想要的项目列表。

你必须对实体继承有点小心。您刚刚看到了它如何使获取变得更加复杂。它还对数据的存储方式有影响,即子实体的所有实例都存储在同一个表中。因此,如果您有十几个派生自Group(例如ToyType)的实体,则所有这些实体的所有实例都存储在一起。

于 2012-08-26T20:05:47.280 回答