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

2024-01-10

给定核心数据实体设置如下

  • Entity A
    • Bs -> B(多对多)
    • Cs -> C(多对多)
    • 孩子 -> 孩子(多对多)
  • Entity B
    • 孩子 -> 孩子(多对多)
  • Entity C
    • 孩子 -> 孩子(多对多)
  • Child
    • date

我想要查询实体 A,其中任何子实体(实体 A、B 或 C 中)的日期都通过某些查询,例如大于指定日期。

考虑到嵌套关系,需要一些嵌套子查询,因此要使用类似这样的方法检查 A 中的所有 B 子查询

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)

对 C 重复相同形式的查询,然后对 A 的直接子级执行单个 SUBQUERY。

在对谓词形式进行一些微调(确保添加了所有所需的计数)后,这一切都工作正常。

当我现在想要执行类似的搜索时,出现了一个小问题,但我不想要求孩子的日期大于测试日期,而是只想查找在 A.children、Bs.children、Cs 中拥有任何孩子的所有 A。孩子们。

嵌套的 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)

快速搜索堆栈溢出在这个问题中发现了同样的错误

Core Data SUBQUERY 和 NSFetchedResultsController 的键路径错误 https://stackoverflow.com/questions/10762539/keypath-error-with-core-data-subquery-and-nsfetchedresultscontroller

这似乎表明您不能在子查询中执行@count,因此必须对子查询执行另一个子查询才能获得相同的结果。这与上面的第一个示例的形式相同,尽管我需要在 SUBQUERY 中设置一个对于子级的每个元素始终成立的条件。我的第一个想法是希望我可以像这样使用 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]

这是可行的,但感觉比我想要的只是计数要多做一些工作。一个更简单的有效示例也只是测试每个孩子是否为零,所以

predicateString += "(SUBQUERY(Bs, $b, SUBQUERY($b.children, $child, $child != nil).@count > 0).@count > 0)"
predicateVars = [testDate! as NSDate]

这看起来好多了,但我只是想知道是否有更好的选择。老实说,我不明白为什么 TRUE 条件本身不是一个有效的谓词。是的,它很浪费,但在这种情况下,我们似乎必须执行一个有效浪费的子查询来获得我们想要的计数。

有人有更好的想法吗?


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NSPredicate 用于检测子查询中的非空关系 的相关文章

随机推荐