给出如下的核心数据实体设置
我想查询实体A的哪个子对象(在实体A,B或C中)的日期都通过了某些查询,例如大于指定的日期。
鉴于嵌套关系,需要一些嵌套的子查询,因此要使用类似这样的方法检查A中所有的Bs子代
predicateString += "(SUBQUERY(Bs, $b, SUBQUERY($b.children, $child, $child.date >= %@).@count > 0).@count > 0)"
predicateVars = [testDate! as NSDate]
let predicate = NSPredicate(format: predicateString, argumentArray: predicateVars)
对Cs重复相同的查询形式,然后对A的直接子代执行一个子查询。
在对谓词形式进行一些微调之后(确保添加了所有必需的计数),所有这些都可以正常工作。
当我现在想执行类似的搜索时,出现了一个小问题,但我不要求孩子的日期大于测试日期,而是想查找所有在A.children,Bs.children中都有孩子的A。 ,Cs.children。
嵌套的SUBQUERIES引起了问题,起初我认为可以做一个单层SUBQUERY,然后检查其中的子级关系数,所以这样
predicateString += " SUBQUERY(Bs, $b, $b.children.@count > 0).@count > 0"
哪个被接受为有效谓词,但是当其被评估时您遇到了异常
[error] error: exception handling request: <NSSQLFetchRequestContext: 0x60000018ec70> , Keypath containing KVC aggregate where there shouldn't be one; failed to handle $b.children.@count with userInfo of (null)
快速搜索堆栈溢出时,在此问题中出现了相同的错误
Keypath error with Core Data SUBQUERY and NSFetchedResultsController
这似乎暗示您不能在子查询中执行@count,因此必须对子项执行另一个子查询才能获得相同的结果。这与我上面的第一个示例的格式相同,尽管我在子查询中需要一个条件,该条件对于子元素的每个元素总是正确的。我的第一个想法是希望我可以像这样使用TRUE
predicateString += "(SUBQUERY(Bs, $b, SUBQUERY($b.children, $child, TRUE).@count > 0).@count > 0)"
感觉很浪费,但是会做我想要的。不幸的是,它无法解析为有效谓词。
除此之外,我设法通过进行始终为真的查询来取得成功,因此将日期与1970年进行如下比较
let date1970 = Date.init(timeIntervalSince1970: 0)
predicateString += "(SUBQUERY(Bs, $b, SUBQUERY($b.children, $child, $child.date >= %@).@count > 0).@count > 0)"
predicateVars = [date1970! as NSDate]
这很有效,但是感觉比我希望得到的计数要多得多。一个更简单有效的示例也只是针对每个孩子测试nil,所以
predicateString += "(SUBQUERY(Bs, $b, SUBQUERY($b.children, $child, $child != nil).@count > 0).@count > 0)"
predicateVars = [testDate! as NSDate]
这看起来好多了,但我只是想知道是否有更好的选择。老实说,我不明白为什么仅TRUE条件不是一个有效的谓词。是的,它是浪费的,但是在这种情况下,我们似乎必须进行有效浪费的子查询才能获得所需的计数。
有人有更好的主意吗?