我有以下模型图:
+-----------+ +-----------+
| 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: ...
我意识到,由于所有者与ToyBox之间是一对一的关系,因此没有返回任何集合,这就是问题所在。所以我的问题是:
1)有没有一种方法可以强制子查询中的一对一关系返回集合?
2)如果没有其他方法可以针对获取请求创建此谓词?
最佳答案
似乎应该比您想做的要简单得多。如果希望所有项目都具有给定的所有者,请从所有者开始并使用键路径获取关联的项目。您不需要谓词。如果您有10罐花生,并且想在2罐中取出花生,那么您就不必先从所有花生中提取花生,然后再根据它们的罐子进行过滤,对吗?首先,您需要获得罐2,然后查看其中包含的花生。这样做:
NSSet *groups = [ownerObject valueForKeyPath:@"toyBox.groups"];
这样就为您提供了
ownerObject
拥有的所有组。您不能仅使用单个键路径来获取所有项目,因为Group
实体没有items
属性。通过给Group
访问器,即使它只返回一个空集,也可以使自己的生活更轻松。那可以让你做到这一点:NSSet *items = [ownerObject valueForKeyPath:@"toyBox.groups.items"];
如果不想向
items
添加items
属性,则必须从第一个示例中过滤集Group
以仅选择那些是ToyType对象的对象。然后,您可以在该集合上使用键路径groups
来获取所需的项目列表。您必须对实体继承有所注意。您已经了解了它如何使获取变得更加复杂。它也影响数据存储方式,即all instances of sub-entities are stored in the same table。因此,如果您有许多来自
@"items"
的实体(例如Group
),则所有这些实体的所有实例都存储在一起。关于objective-c - 跨一对一关系的核心数据获取请求谓词过滤,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12133396/