Проблема с предикатом данных ядра «один ко многим» и «многие к одному»

#core-data #nsfetchedresultscontroller #nspredicate

#core-data #nsfetchedresultscontroller #nspredicate

Вопрос:

У меня есть объекты Client и объекты Job.

У каждого задания может быть один клиент. Связь для заданий клиента (client<—>>job) называется jobOfClient.

У каждого клиента может быть много заданий. Связь для клиента задания (job<<—>client) называется clientOfJob.

(Конечно, это обратные отношения.)

У меня есть несколько предикатов, которые работают, но последний не работает. Не учитывая некоторые настройки fetchedResultsController, вот некоторые ключевые строки кода для трех случаев:

Здесь я просматриваю задания, ища задания, которые не связаны ни с одним клиентом:

 NSEntityDescription * entity = [NSEntityDescription entityForName:@"Job" inManagedObjectContext:dataInterface.managedObjectContext];

NSPredicate *predicate = [NSPredicate predicateWithFormat: @"clientOfJob == nil"];
  

Здесь я перебираю задания, ища задания конкретного клиента:

 NSEntityDescription * entity = [NSEntityDescription entityForName:@"Job" inManagedObjectContext:dataInterface.managedObjectContext];
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"clientOfJob == %@", userState.selectedClient];
  

Но этот следующий не работает. Здесь я перебираю клиентов, ища одного клиента, связанного с выбранным заданием (или не возвращаю результата, если нет связанного клиента, но здесь это не тот случай).

 NSEntityDescription * entity = [NSEntityDescription entityForName:@"Client" inManagedObjectContext:dataInterface.managedObjectContext];    
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"jobOfClient == %@", userState.selectedJob];
  

Сообщение об ошибке завершает работу приложения из-за неперехваченного исключения ‘NSInvalidArgumentException’, причина: ‘ключ to-many здесь не разрешен’

Здесь должно быть что-то тонкое, чего я не понимаю. Может ли кто-нибудь помочь мне с ** информацией, которую я предоставил?

Ответ №1:

jobOfClient вернет коллекцию объектов, что означает, что ваш предикат по существу выполняет:

 NSSet *jobs = [thisObject jobOfClient];
return ([jobs isEqual:aJob]);
  

Очевидно, что коллекция никогда не равна одному значению, и поэтому CoreData не распознает предикат. Чтобы обойти это, я думаю, вы можете сделать:

 [NSPredicate predicateWithFormat:@"jobOfClient CONTAINS %@", [userState selectedJob]];
  

И чтобы убедиться, что вы не столкнетесь с этим снова, я бы рекомендовал изменить название этого отношения с jobOfClient на просто jobs (используя форму множественного числа, чтобы указать, что это отношение «ко многим», и исключить OfClient , потому что оно уже есть в Client сущности). Ваши другие отношения, вероятно, следует переименовать аналогичным образом. clientOfJob => client и т.д.

Комментарии:

1. Спасибо. Я смог решить проблему, используя это: NSPredicate *predicate = [NSPredicate predicateWithFormat: @»ANY jobOfClient == % @», UserState.selectedJob]; — Ключевое слово any заставило его просмотреть все в наборе.