J'ai un modèle de données de base dans lequel une entité de tâche inclut une relation facultative à plusieurs exclusOccurrences. L'une des propriétés de exclusOccurrences est start, qui est un objet NSDate. L'entité ExcludedOccurrence a une relation inversée obligatoire à une avec l'entité Task.
Afin de récupérer des tâches pour un jour spécifié, je dois m'assurer que le jour spécifié n'apparaît pas en tant que propriété de début d'une entité ExcludedOccurrence. L'un des sous-prédicats que j'essaie d'utiliser est donc
NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"(ALL excludedOccurrences.start != %@))", today];
où today est un objet NSDate pour aujourd'hui comprenant uniquement les composants jour, mois et année. Toutes les propriétés de début des occurrences exclues incluent également uniquement les composants jour, mois et année.
Bien que cela devrait fonctionner correctement, au moins en lisant la documentation de Core Data et NSPredicate, j'obtiens le message d'erreur suivant:
Arrêt de l'application en raison d'une exception non interceptée 'NSInvalidArgumentException', raison: 'Prédicat non pris en charge
Si j'utilise le prédicat équivalent
NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"!(ANY excludedOccurrences.start == %@))", today];
aucune exception n'est levée, mais le code ne fonctionne pas comme prévu: l'occurrence d'aujourd'hui, qui ne doit pas être exclue, est à la place exclue.
Je ne sais pas aussi comment tester le cas excluOccurrences == nil: le prédicat suivant
NSPredicate *nilPredicate = [NSPredicate predicateWithFormat: @"(excludedOccurrences == nil)"];
provoque à l'exécution l'exception
clé to-many non autorisée ici
Cependant, étant donné que la relation exclueOccurrences est facultative, je dois également tester si elle est nulle.
Comment gérer cela? Merci d'avance.
avec l'aide de vous tous, j'ai finalement réussi à déterminer le bon prédicat pour mon scénario. Il semble qu'un objet NSDate soit traité comme un double, cependant, le double n'est jamais quelque chose comme 3.7, c'est toujours comme 3.0 Par conséquent, le prédicat suivant fonctionne correctement dans mes tests:
NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"(excludedOccurrences.@count == 0 || (excludedOccurrences.@count > 0 && NONE excludedOccurrences.start == %@))",thisDate];
où thisDate est un objet NSDate contenant uniquement les composants jour, mois et année (comme dans le cas de la propriété start de l'entité ExcludedOccurrence.
Le test d'une relation vide se fait essentiellement à l'aide de l'opérateur d'agrégation @count, comme suggéré par certains chez Apple.
Encore une fois, merci beaucoup pour votre aide. J'observe toujours que la documentation est imparfaite en plusieurs parties (en particulier là où il est dit que TOUT fonctionne bien alors qu'au lieu de cela, cela ne fonctionne pas du tout).
Pour tester une relation vide, vous devez comparer le nombre de clés to-many à zéro.
[NSPredicate predicateWithFormat:@"excludedOccurrences.@count == 0"];
En ce qui concerne vos sous-prédicats, sachez que vous ne pouvez avoir que l'un des modificateurs ALL
ou ANY
dans votre prédicat final, bien que vous puissiez utiliser ce modificateur plusieurs fois dans le prédicat.
Pas OK: ANY foo.bar = 1 AND ALL foo.baz = 2
OK:ANY foo.bar = 1 AND !(ANY foo.baz != 2)
Donc, pour tester une relation non vide, cela fonctionne réellement:
[NSPredicate predicateWithFormat:@"relationship.@count != 0"]
La solution proposée par Ashley Clark se bloque pour moi en donnant "la clé à plusieurs n'est pas autorisée ici"
Et dans Swift 2, quelque chose comme:
request.predicate = NSPredicate(format: " relationship.@count != 0")