首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跨一对一关系的核心数据获取请求谓词过滤

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

Stack Overflow用户
提问于 2012-08-27 03:55:49
回答 1查看 1.3K关注 0票数 0

我有以下模型图:

代码语言:javascript
复制
                  +-----------+     +-----------+
                  | Container |     |   Group   |
                  +-----------+     +-----------+
                  |  groups   |<-->>| container |
                  +-----------+     +-----------+
                        ^                 ^
                        |                 |
+-----------+     +-----------+     +-----------+     +---------+
|   Owner   |     |  ToyBox   |     |  ToyType  |     |  Item   |
+-----------+     +-----------+     +-----------+     +---------+
|  toyBox   |<--->|   owner   |     |   items   |<-->>| toyType |
+-----------+     +-----------+     +-----------+     +---------+

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

由于父实体的原因,尝试使用keypath谓词会导致异常。这似乎是Apple的错误或不支持的决定。雷达已经被归档了。此外,我不希望扁平化实体。

因此,我尝试使用SUBQUERY()如下所示:

代码语言:javascript
复制
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];

这将导致以下异常:

代码语言:javascript
复制
Can't have a non-relationship collection element in a subquerySUBQUERY($c.owner, $o, $o == <MLMOOwner: ...

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

1)是否有办法在子查询中强制返回一对一关系的集合?

2)如果没有,是否有其他方法可以为fetch请求创建此谓词?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-27 04:05:47

看起来做你想做的事情要简单得多。如果您希望所有项都具有给定的所有者,请从所有者开始,并使用密钥路径来获取关联的项。您不需要谓词。如果您有10个花生罐,您想要检索jar 2中的花生,您不会从所有花生的集合开始,然后根据它们的罐子对它们进行过滤,对吗?您首先得到jar 2,然后查看它包含的花生。所以要这样做:

代码语言:javascript
复制
NSSet *groups = [ownerObject valueForKeyPath:@"toyBox.groups"];

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

代码语言:javascript
复制
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),那么所有这些实体的所有实例都存储在一起。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12133396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档