具有多对多关系的核心数据 - 在 SUBQUERY 中使用 ALL 创建 NSPredicate

Posted

技术标签:

【中文标题】具有多对多关系的核心数据 - 在 SUBQUERY 中使用 ALL 创建 NSPredicate【英文标题】:Core Data with to Many relationship - Creating a NSPredicate with ALL in SUBQUERY 【发布时间】:2011-07-22 23:27:20 【问题描述】:

我的对象图是这样的

SnapShot -->> 窗格 --> ManagedImage

我正在尝试找到一个 SnapShot,其中包含的确切 ManagedImages 包含在集合中。

我现在得到的代码返回一个快照数组,其中包含一个或多个集合中的 ManagedImage。然后我在数组中搜索以找到正确的快照,但我猜在子查询中过滤会快得多

使用 NSPredicate 如何获得具有集合中所有 ManagedImages 的唯一 SnapShot?

这是我的代码

mySet = ... // A unique set of (usually 3) managedImages that I'm trying to find a snapShot for

NSFetchRequest *request = ...
request.entity = [NSEntityDescription entityForName:@"SnapShot" inManagedObjectContext:[self managedObjectContext]];

// Want this to work but sends an exception
//request.predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(self.panes, $pane, ALL $pane.managedImage IN %@).@count != 0", mySet];

// Using this
request.predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(self.panes, $pane, $pane.managedImage IN %@).@count != 0", mySet];

【问题讨论】:

【参考方案1】:

一个好的经验法则是,如果您已经拥有托管对象,则无需获取而是将关系从您拥有的托管对象转移到您想要的托管对象。

因此,您的关系图实际上可能如下所示:

SnapShot <-->> Pane <--> ManagedImage

或者也许:

SnapShot <<-->> Pane <<--> ManagedImage

由于您有一组ManagedImage 对象,您所要做的就是遍历pane.snapShotpanes.snapShots 的键路径以找到与每个ManagedImage 对象关联的SnapShot 对象。然后,您只需提取唯一的 SnapShot 对象。

第一种情况,因为是一对一的关系路径,所以事情是小事一桩

ManagedImage-->Pane-->SnapShot

在第二种情况下,您需要先获取所有唯一的 SnapShot 对象:

NSSet *shots=[aMangedImageObj valueForKeyPath:@"distinctUnionOfSets.panes.snapShots"];

...对于每个ManagedImage 实例,然后将所有集合与setByAddingObjectsFromSet: 或类似方法合并以生成一组唯一对象。

Fetches 应该用于在图中找到您需要的第一个对象,但是一旦您拥有这些对象,您就不会获取而是遍历关系。否则,首先建立关系没有多大意义。

【讨论】:

以上是关于具有多对多关系的核心数据 - 在 SUBQUERY 中使用 ALL 创建 NSPredicate的主要内容,如果未能解决你的问题,请参考以下文章

核心数据。加入 2 个具有多对多关系的表?

具有多对多关系的核心数据 NSPredicate

将对象添加到具有多对多关系的核心数据中的 NSSet

从具有多对多关系核心数据iOS的上下文中删除nsmanagedboject

通过 HTTP 导入核心数据,具有多对多关系

NSFetchRequest GroupBy 一对多关系的属性