带有日期范围的 CoreData 复合提取的意外结果

Unexpected result from CoreData compound fetch with date range

我有一个简单的数据模型,其中访问者(fName 和 lName)和访问(日期、评论)之间存在 1-m 关系。我正在尝试获取特定日期的所有访问者。为了实现这一点,我需要创建一个谓词来查找在当天开始和结束之间进行访问的所有实体。我试过:

...
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "visitor")
let filter = "ANY visits.date >= %@ AND ANY visits.date < %@"  // visits is the visitors relation to visits
let startTime = calendar.startOfDay(for: thisDay) as NSDate
let endTime = calendar.date(bySettingHour: 23, minute: 59, second: 59, of: thisDay)! as NSDate
fetchRequest.predicate = NSPredicate(format: filter, startTime, endTime)

结果是访问日期在这一天及之后的所有访问者。因此,复合谓词的第二部分无效! 我还尝试将这两个条件与 NSCompoundPredicate 结合起来,但结果是一样的。我已经用相同的复合谓词尝试了除日期类型之外的其他类型,并且这些都运行良好。因此,尽管在 Internet 上进行了大量搜索,但我不知道如何使用谓词来解决这个简单的查询。

欢迎提出任何建议!

您的谓词获取所有与(至少一次)访问 visits.date >= startDate 和(至少一次)访问 visits.date < endDate 相关的访问者。问题是对于 return true.

的谓词,这两个相关对象不必相同

你需要的是一个“子查询”:来自(相关)NSExpression documentation:

This method creates a sub-expression, evaluation of which returns a subset of a collection of objects. It allows you to create sophisticated queries across relationships, such as a search for multiple correlated values on the destination object of a relationship.

...

The string format for a subquery expression is:

SUBQUERY(collection_expression, variable_expression, predicate);

where expression is a predicate expression that evaluates to a collection, variableExpression is an expression which will be used to contain each individual element of collection, and predicate is the predicate used to determine whether the element belongs in the result collection.

在你的情况下应该是(未经测试):

NSPredicate(format: "SUBQUERY(visits, $v, $v.date >= %@ and $v.date < $@).@count > 0",
            startTime, endTime)

这将获取与至少一次日期在指定范围内的访问相关的所有访问者。