Сложный NSPredicate, проходящий через несколько сущностей и типы отношений - PullRequest
0 голосов
/ 23 августа 2011

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

ИЗДАТЕЛЬ << --- >> ИЗДАТЕЛЬ << - КНИГА << ---> АВТОР << ->> АГЕНТЫ

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

NSArray *agentNames = [NSArray arrayWithObjects:Dan, Hunter, Sloan, Jackson];

NSFetchRequest *request = [[NSFetchRequest alloc] init];

request.entity = [NSEntityDescription entityForName:@"Publisher" inManagedObjectContext:context];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor
             sortDescriptorWithKey:@"publisherName" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] ];
request.predicate = [NSPredicate predicateWithFormat:@"ANY pubHouse.publicist.assignedBook.authorRep.agentName IN %@", [agentNames valueForKey:@"agentName"]];
request.fetchBatchSize = 20;

    NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];

Когда я запускаю предыдущий предикат, я получаю следующеепредупреждение:

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unimplemented SQL generation for predicate : ANY pubHouse.publicist.assignedBook.authorRep.agentName IN

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

Ответы [ 3 ]

6 голосов
/ 23 августа 2011

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

С этой моделью данных:

PUBLISHER<< --- >>PUBLICIST<<-->BOOK<<--->AUTHOR<<-->>AGENTS

... ваш путь к ключу:

pubHouse.publicist.assignedBook.authorRep.agentName

… с точки зрения объектов и набора отношений выглядит примерно так:

object.set.object.object.set

Итак, это два набора, к которым ANY может относиться.

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

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

NSArray *agentNames = [NSArray arrayWithObjects:Dan, Hunter, Sloan, Jackson];
request.entity = [NSEntityDescription entityForName:@"Agent" inManagedObjectContext:context];
request.predicate = [NSPredicate predicateWithFormat:@"agentName IN %@", agentNames];

Тогда вы пройдете по ключевому пути отношений:

authors.books.publicist.publishers 

… чтобы найти всех связанных издателей.

Я думаю, что у вас будут проблемы, независимо от того, что вы делаете, потому что у вас более одного отношения «многие ко многим», например.

PUBLISHER<<--->>PUBLICIST

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

0 голосов
/ 23 августа 2011

Возможно, NSArray имеет проблему с valueForKey:. Я видел решение, использующее NSCompoundPredicate для добавления элементов массива в цикл.

Кстати, в вашей цепочке множественных отношений, вы не скучаете по своим авторам ?

0 голосов
/ 23 августа 2011

Просто оберните предложение IN строки предиката в скобках:

@"ANY (pubHouse.publicist.assignedBook.authorRep.agentName IN %@)"

Был бы рад узнать, работает ли он.

...