Основные данные, ключ NSPredicate и to-many

У меня есть модель Core Data, в которой объект Task включает необязательное отношение to-many excludedOccurrences. Одним из свойств excludedOccurrences является запуск, который является объектом NSDate. Объект ExcludedOccurrence имеет обратное обязательное отношение к одному объекту Task.

Чтобы получать задания за указанный день, мне нужно убедиться, что указанный день не отображается как свойство start любого объекта ExcludedOccurrence. Поэтому один из суб-предикатов, который я пытаюсь использовать,

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"(ALL excludedOccurrences.start != %@))", today];

где сегодня есть объект NSDate на сегодняшний день, включая только компоненты дня, месяца и года. Все свойства запуска исключенных вхождений также включают компоненты дня, месяца и года.

Хотя это должно быть хорошо, по крайней мере, для чтения документации для Core Data и NSPredicate, я получаю следующее сообщение об ошибке:

Завершение приложения из-за неперехваченного исключения "NSInvalidArgumentException", причина: "Неподдерживаемый предикат

Если я использую эквивалентный предикат

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"!(ANY excludedOccurrences.start == %@))", today];

исключение не генерируется, однако код работает не так, как ожидалось: исключение из этого списка, которое не должно быть исключено.

Я также не уверен, как тестировать для case excludedOccurrences == nil: следующий предикат

NSPredicate *nilPredicate = [NSPredicate predicateWithFormat: @"(excludedOccurrences == nil)"];

вызывает во время выполнения исключение

to-many не разрешено здесь

Однако, поскольку отношение excludedOccurrences не является обязательным, мне также нужно проверить, нет ли он.

Как я могу справиться с этим? Заранее благодарю вас.

Ответ 1

с помощью всех вас, наконец, мне удалось определить правильный предикат для моего сценария. Похоже, что объект NSDate обрабатывается как double, однако double никогда не является чем-то вроде 3.7, он всегда как 3.0 Поэтому в моих тестах корректно работает следующий предикат:

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"([email protected] == 0 || ([email protected] > 0 && NONE excludedOccurrences.start == %@))",thisDate];

где thisDate является объектом NSDate, содержащим только компоненты day, month и year (как в случае свойства start объекта ExcludedOccurrence.

Тестирование пустых отношений в основном выполняется с помощью оператора агрегации @count, как это было предложено некоторыми людьми в Apple.

Опять же, большое спасибо за вашу помощь. Я все еще замечаю, что документация ошибочна в нескольких частях (особенно там, где говорится, что ВСЕ работает нормально, а вместо этого она вообще не работает).

Ответ 2

Чтобы проверить пустое отношение, вы должны сравнить количество ключей to-many с нолем.

[NSPredicate predicateWithFormat:@"[email protected] == 0"];

Что касается ваших субпредактов, имейте в виду, что вы можете иметь только один из модификаторов ALL или ANY в своем конечном предикате, хотя вы можете использовать этот модификатор несколько раз по всему предикату.

Не в порядке: ANY foo.bar = 1 AND ALL foo.baz = 2
ОК: ANY foo.bar = 1 AND !(ANY foo.baz != 2)

Ответ 3

Итак, чтобы проверить непустое отношение, это действительно работает:

[NSPredicate predicateWithFormat:@"[email protected] != 0"]

Решение, данное Эшли Кларк, разбивается, потому что я даю мне "ключ для многих",

Ответ 4

И в swift 2, что-то вроде:

request.predicate = NSPredicate(format: " [email protected] != 0")