NSPredicate检测子查询中的非空关系

时间:2018-08-08 18:04:37

标签: core-data nspredicate

给出如下的核心数据实体设置

  • 实体A
    • Bs-> B(很多)
    • Cs-> C(很多)
    • 孩子->孩子(很多)
  • 实体B
    • 孩子->孩子(很多)
  • 实体C
    • 孩子->孩子(很多)
  • 儿童
    • 日期

我想查询实体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条件不是一个有效的谓词。是的,它是浪费的,但是在这种情况下,我们似乎必须进行有效浪费的子查询才能获得所需的计数。

有人有更好的主意吗?

0 个答案:

没有答案