Базовые данные, попробуйте использовать NSPredicate для фильтрации набора отношений toMany, но получите ошибку «ключ ко многим здесь не разрешен» - PullRequest
6 голосов
/ 05 сентября 2010

Вот модель, которая у меня есть: http://www.girardet.ch/model.png

Моя цель - получить все цитаты по следующим критериям:

  • принадлежат определенной теме: атрибут name_en тем
  • по релевантности
  • отфильтровано по авторам (с псевдонимом Authors)

Вот мой код:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ThemeEntries" inManagedObjectContext:_context];
[fetchRequest setEntity:entity];

NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"relevancy" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
[fetchRequest setSortDescriptors:sortDescriptors];

// predictate - filter
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"theme.name_en=%@ AND quotes.author.alias=%@",@"mytheme", @"myauthor"];

[fetchRequest setPredicate: предикат];

Я получаю сообщение об ошибке "ключ ко многим здесь не разрешен".

Если я вместо этого использую этот предикат

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"theme.name_en=%@, @"mytheme"];

это работает хорошо, и я могу циклически перебрать ThemeEntries, которое я получаю, и получить все мои цитаты ... Но это не фильтруется авторами.

Что я могу сделать, чтобы отфильтровать по авторам?

1 Ответ

26 голосов
/ 05 сентября 2010

Ваша проблема в том, что отношение одного из вас - это ключевой путь «многие-ко-многим», и предикат не знает, какой именно объект идет с каким.

У вас есть ThemeEntities<<-->>Quotes, который производит набор на каждом конце.Путь к ключу quotes.author.alias говорит «набор экземпляров кавычек, каждый из которых связан с экземплярами автора, который в свою очередь имеет атрибут псевдонима».Предикат не может обрабатывать множество.

Вам нужно использовать подзапрос, чтобы перейти к многим путям.Подзапрос, по сути, является вложенным предикатом, который ищет набор и возвращает другой набор объектов, соответствующий вложенному предикату.Подзапросы плохо документированы, но имеют форму:

SUBQUERY(collectionName,$collectionElementVariable,expression-with-$collectionElementVariable)

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

@"theme.name_en=%@ AND (0!=SUBQUERY(quotes,$eachQuote,$eachQuote.author.alias=%@).@count)",@"mytheme", @"myauthor"

Подзапрос говорит: «Из набора кавычек возьмите каждый объект цитаты и проверьте, имеет ли его объект отношения автора с псевдонимом атрибут, соответствующий« myauthor ».количество объектов кавычек с этим соответствием. Если число не равно нулю, верните ИСТИНА. "

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

...