Есть ли более эффективная альтернатива, чтобы найти объект, имеющий отношение «один к одному» с двумя имеющимися у меня объектами? - PullRequest
0 голосов
/ 15 марта 2011

У меня есть следующие настройки основных данных:

Project has-many Answer
Field has-many Answer
Answer has-one Field
Answer has-one Project

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

NSEntityDescription *answerEntity = [NSEntityDescription entityForName:@"Answer" inManagedObjectContext:self.managedObjectContext];
NSPredicate *answerPredicate = [NSPredicate predicateWithFormat:@"ANY project == %@ && field == %@", self.project, self.field];          
NSFetchRequest *answerRequest = [[NSFetchRequest alloc] init];
[answerRequest setEntity:answerEntity];
[answerRequest setPredicate:answerPredicate];

NSError *error = nil;
NSArray *predicates = [self.managedObjectContext executeFetchRequest:answerRequest error:&error];

Я все еще новичок в Core Data, но я считаю, что fetchRequest запрашивает базу данных каждый раз, когда я ее вызываю, есть ли более эффективный способ найти эти объекты ответа?

Ответы [ 2 ]

1 голос
/ 16 марта 2011

Если я правильно понимаю, у вас уже есть объект Field и объект Project, и вы хотите найти общие для них объекты ответа.

Если это так, решение представляет собой простую операцию пересечения множеств:

NSSet *answersInCommon=[[aFieldObj mutableSetValueForKey:@"answers"] intersectSet:[aProjectObj mutableSetValueForKey:@"answers"]];

..., которая будет возвращать только те объекты ответа, которые появляются в обоих отношениях.

Обновление:

@ pdenya в комментарии предоставляет улучшение:

Просто хочу уточнить небольшую ошибку и небольшой момент, который делает это не идеальным.intersectSet возвращает (void), поэтому синтаксис для этого будет:

NSMutableSet *answers=[field mutableSetValueForKey:@"answers"]; 
[answers intersectSet:[project mutableSetValueForKey:@"answers"]]; 

Это решение также изменяет массив aFieldObj.answers, что означает, что вы не можете использовать его во время итерации.setWithSet очищает это право.Пример:

NSMutableSet *answers = [NSMutableSet setWithSet:[project mutableSetValueForKey:@"answers"]]; 
[answers intersectSet:[field mutableSetValueForKey:@"answers"]];

@ pdenya - это правильная форма.

0 голосов
/ 15 марта 2011

Лучший альтернативный метод, который я нашел до сих пор:

NSMutableSet *answers = [self.project mutableSetValueForKey:@"answers"];
NSPredicate *answerPredicate = [NSPredicate predicateWithFormat:@"field == %@", field];
[answers filterUsingPredicate:answerPredicate];

NSManagedObject *answer = nil;
if([answers count] > 0) {
    answer = [[answers allObjects] objectAtIndex:0];
}
...