NSPredicate 核心数据中的多对多关系
NSPredicate on multiple to-many relationships in Core Data
我有一个 NSPredicate
,其中包含多个聚合过滤器,它抛出异常。
我有以下核心数据模型:
我想选择 ApparelItems
中任何 colours
的 rgb
为 13576743,并且所有 picks
的 pickTime
早于给定的 NSDate
.
我创建谓词的代码是:
let request = NSFetchRequest(entityName: "ApparelItem")
var predicates = [NSPredicate]()
predicates.append(NSPredicate(format: "ANY colours.rgb = 13576743"))
// find the NSDate representing midnight x days ago
let cal = NSCalendar.currentCalendar()
if let xDaysAgo = cal.dateByAddingUnit(.Day, value: -2, toDate: NSDate(), options: [])
{
let midnightXDaysAgo = cal.startOfDayForDate(xDaysAgo)
predicates.append(NSPredicate(format: "(ALL picks.pickTime < %@)", midnightXDaysAgo))
}
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
let searchData = try? objectContext.executeFetchRequest(request)
我得到以下异常:
Exception name=NSInvalidArgumentException, reason=Unsupported predicate (ANY colours.rgb == 13576743) AND ALL picks.pickTime < CAST(479347200.000000, "NSDate")
我试过:
每个谓词都可以正常工作。即 ANY colours.rgb = ...
有效,ALL picks.pickTime < ...
也有效。当合并到同一个查询中时,它们就不起作用了。
将两者结合到一个查询中,与 AND
链接,而不是使用 NSCompoundPredicate
。结果是一样的
有没有可能核心数据根本不支持对多于一对多的关系进行过滤?这看起来很奇怪。在什么情况下我应该怎么做?
可能可以尝试 SUBQUERY()
换 NSPredicate
。
下面的代码是我猜测出来的,不太确定它是否有效。通常,对于带有 NSPredicate
.
的多对多查询子句,我会反复试验很多次
var predicates = [NSPredicate]()
predicates.append(NSPredicate(format: "SUBQUERY(colours, $colour, ANY $colour.rgb = 13576743).@count > 0"))
let cal = NSCalendar.currentCalendar()
if let xDaysAgo = cal.dateByAddingUnit(.Day, value: -2, toDate: NSDate(), options: []) {
let midnightXDaysAgo = cal.startOfDayForDate(xDaysAgo)
predicates.append(NSPredicate(format: "SUBQUERY(picks, $pick, ALL $pick.pickTime < %@).@count > 0", midnightXDaysAgo))
}
颜色和选择是两个不同的实体,因此您应该能够在不使用 SUBQUERY
的情况下按两者进行过滤。一个谓词或复合谓词都应该没问题。
从错误消息来看,日期似乎有问题。请检查您的托管对象子类中是否具有预期的数据类型。如果您在创建子类时使用了 "primitive values",则需要 NSTimeInterval
而不是 NSDate
。
我有一个 NSPredicate
,其中包含多个聚合过滤器,它抛出异常。
我有以下核心数据模型:
我想选择 ApparelItems
中任何 colours
的 rgb
为 13576743,并且所有 picks
的 pickTime
早于给定的 NSDate
.
我创建谓词的代码是:
let request = NSFetchRequest(entityName: "ApparelItem")
var predicates = [NSPredicate]()
predicates.append(NSPredicate(format: "ANY colours.rgb = 13576743"))
// find the NSDate representing midnight x days ago
let cal = NSCalendar.currentCalendar()
if let xDaysAgo = cal.dateByAddingUnit(.Day, value: -2, toDate: NSDate(), options: [])
{
let midnightXDaysAgo = cal.startOfDayForDate(xDaysAgo)
predicates.append(NSPredicate(format: "(ALL picks.pickTime < %@)", midnightXDaysAgo))
}
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
let searchData = try? objectContext.executeFetchRequest(request)
我得到以下异常:
Exception name=NSInvalidArgumentException, reason=Unsupported predicate (ANY colours.rgb == 13576743) AND ALL picks.pickTime < CAST(479347200.000000, "NSDate")
我试过:
每个谓词都可以正常工作。即
ANY colours.rgb = ...
有效,ALL picks.pickTime < ...
也有效。当合并到同一个查询中时,它们就不起作用了。将两者结合到一个查询中,与
AND
链接,而不是使用NSCompoundPredicate
。结果是一样的
有没有可能核心数据根本不支持对多于一对多的关系进行过滤?这看起来很奇怪。在什么情况下我应该怎么做?
可能可以尝试 SUBQUERY()
换 NSPredicate
。
下面的代码是我猜测出来的,不太确定它是否有效。通常,对于带有 NSPredicate
.
var predicates = [NSPredicate]()
predicates.append(NSPredicate(format: "SUBQUERY(colours, $colour, ANY $colour.rgb = 13576743).@count > 0"))
let cal = NSCalendar.currentCalendar()
if let xDaysAgo = cal.dateByAddingUnit(.Day, value: -2, toDate: NSDate(), options: []) {
let midnightXDaysAgo = cal.startOfDayForDate(xDaysAgo)
predicates.append(NSPredicate(format: "SUBQUERY(picks, $pick, ALL $pick.pickTime < %@).@count > 0", midnightXDaysAgo))
}
颜色和选择是两个不同的实体,因此您应该能够在不使用 SUBQUERY
的情况下按两者进行过滤。一个谓词或复合谓词都应该没问题。
从错误消息来看,日期似乎有问题。请检查您的托管对象子类中是否具有预期的数据类型。如果您在创建子类时使用了 "primitive values",则需要 NSTimeInterval
而不是 NSDate
。