使用 JOIN 访问 NSPredicate 中的核心数据实体关系

Posted

技术标签:

【中文标题】使用 JOIN 访问 NSPredicate 中的核心数据实体关系【英文标题】:Accessing Core Data Entity Relationship in NSPredicate with JOIN 【发布时间】:2014-08-28 00:23:20 【问题描述】:

我最近从直接 SQLite(使用 FMDB)切换到 Core Data,所以我将一堆查询重写为NSPredicates。我不知道如何用谓词做JOIN

我有一个 Entry 实体,它与 Aircraft 实体具有 一对一 关系。

Entry 有一个名为duration 的属性,Aircraft 有一个名为categoryClass 的属性。

我可以像这样总结所有duration 值(假设我之前设置了contextrequest):

//SQLite equivalent: SELECT TOTAL(duration) FROM entry    

NSArray *entries = [context executeFetchRequest:request error:&error];
NSNumber *totalDuration = [entries valueForKeyPath:@"@sum.duration"];

但现在我想对某些类型的飞机的所有duration 值求和:

//SQLite equivalent: SELECT TOTAL(duration) FROM entry LEFT JOIN aircraft ON entry.aircraftRegistration = aircraft.aircraftRegistration WHERE aircraft.categoryClass != 'Simulator' AND aircraft.categoryClass != 'Flight Training Device'"

NSArray *entries = [context executeFetchRequest:request error:&error];
NSNumber *totalDuration = [entries valueForKeyPath:@"@sum.duration ?????"];

我猜这对于简写 @sum 表示法是不可能的,我可能不得不在我的 fetch 请求中使用 NSPredicate,但我不知道如何使用 LEFT JOIN on谓词:

//This results in a crash
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"entry.aircraft.categoryClass != 'Simulator'"];

谁能帮忙?

【问题讨论】:

【参考方案1】:

我想通了。我像以前一样拉出完整的条目列表:

NSArray *entries = [context executeFetchRequest:request error:&error];

然后在该数组上,我应用另一个谓词,该谓词使用关系 Aircraft 实体上的条件,如下所示:

NSPredicate *predicateWithoutSim = [NSPredicate predicateWithFormat:@"aircraft.categoryClass != 'Simulator'"];
NSArray *entriesWithoutSim = [entries filteredArrayUsingPredicate:predicateWithoutSim];

然后我可以像以前一样对持续时间求和,但是在新过滤的数组上:

totalDuration = [entriesWithoutSim valueForKeyPath:@"@sum.duration"];

哇哦! :)

【讨论】:

以上是关于使用 JOIN 访问 NSPredicate 中的核心数据实体关系的主要内容,如果未能解决你的问题,请参考以下文章

带有核心数据对象的 NSPredicate

使用 NSPredicate 过滤 NSDictionary 中的值并返回键数组

使用 NSPredicate 过滤对象中的数组

我可以使用 NSPredicate 作为 NSDictionary 中的键吗

使用 NSPredicate 过滤核心数据中的对象

Cocoa 中的自定义 NSPredicate