Базовые данные: предикат, который возвращает объекты другого объекта - PullRequest
1 голос
/ 06 июля 2011

В моей модели данных есть две сущности: Details и Lookup. Мне нужно найти все Details объекты, связанные с конкретным Lookup объектом, который имеет определенное значение атрибута, а затем вернуть эти Details объекты через контроллер полученных результатов.

Мои NSManagedObjectSubclasses:

@interface Details : NSManagedObject {
@privateI 
}
@property (nonatomic, retain) NSString * owner;
@property (nonatomic, retain) NSString * introduction;
@property (nonatomic, retain) NSString * id;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSString * created;
@property (nonatomic, retain) NSString * modified;
@property (nonatomic, retain) NSNumber * type;
@property (nonatomic, retain) NSString * desc;


@interface Lookup : NSManagedObject {
@private
}
@property (nonatomic, retain) NSDate * search_date;
@property (nonatomic, retain) NSString * search_phrase;
@property (nonatomic, retain) NSSet* searchResults;

Мне нужно найти объект Lookup на основе его атрибута search_phrase, а затем получить все связанные объекты Details и вернуть их в выбранный контроллер результатов.

Я думаю, что сначала мне нужно найти объект Lookup, а затем пройтись по объектам NSSet of Detail, но я не знаю, как вернуть их в NSFetchedResultsController.

Я пробовал:

NSPredicate *predicate =[NSPredicate predicateWithFormat:@"search_phrase = %@", self.searchPhrase];

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

fetchRequest.predicate = predicate;

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Lookup" inManagedObjectContext:self.context];

[fetchRequest setEntity:entity];

NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"search_phrase" ascending:NO];

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.context sectionNameKeyPath:nil cacheName:@"Searches"];

У меня есть запрос, который находит правильный Lookup объект, но я не знаю, как получить связанные Detail объекты из выбранного контроллера результатов.

Ответы [ 2 ]

2 голосов
/ 07 июля 2011

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

@property (nonAtomic,retain) Lookup *lookup;

Наличие взаимных отношений позволяет вам находить Detail объекты, начиная с объекта Lookup, и позволяет вам находить объект Lookup, начинающийся с объекта Detail.

Если вы хотите, чтобы в табличном представлении отображался список Detail объектов, вам необходимо настроить запрос выборки контроллера выборки для выборки против сущности Detail.Как правило, вы всегда устанавливаете объект запроса выборки на объект, чьи объекты вы хотите отобразить в табличном представлении.

Предикат также будет запущен для сущности Detail, поэтому вам нужен предикат, который оценивает путь ключа, начинающийся со свойства сущности Detail.В этом случае нам нужны все объекты Details, чей связанный объект Lookup имеет атрибут search_phase, равный предоставленному значению.Итак:

NSPredicate *p=[NSPredicate predicateWithFormat:@"lookup.search_phrase==%@", self.searchPhrase];

Теперь настройте ваш запрос на выборку следующим образом:

  NSFetchRequest *fetch=[[NSFetchRequest alloc] init];
  NSEntityDescription *detailsEntity=[NSEntityDescription entityForName:@"Details" inManagedObjectContext:self.context];
  [fetch setEntity:detailsEntity];
  [fetch setPredicate:p];
  //.. set up a sort however you want the details to appear in the tableview

Дайте эту выборку вашему NSFetchedResultsController, и он вернет Detail объектов, которые вы ищете.

В итоге:

  • Всегда используйте взаимные отношения в модели данных, чтобы иметь гибкость.
  • При использовании контроллера выборочных результатов задайте объектполучить запрос к объекту, чьи объекты вы хотите отобразить в виде таблицы.
1 голос
/ 06 июля 2011

Трудно ответить без некоторого вашего примера кода или даже фактических отношений, но здесь идет речь:

  • Выполните ваш начальный фильтр в таблице A. Это даст вам набор результатов, содержащий рядobjects.
  • Запросите таблицу B с вашим фильтром и AND #Put name of the relationship here# IN (the results of 1)

Что-то еще, что нужно добавить, однако вам следует перестать думать о базовых данных как о реляционной базе данных.Это граф объектов.Базовые данные могут использовать или не использовать разные таблицы для хранения данных.Вы должны быть обеспокоены объектами и их отношениями.

Если я правильно понимаю, вы действительно не хотите, чтобы 1 ко многим, но многие ко многим.После этого вы сможете выполнить оба запроса одновременно с запросом для объектов B:

A.your.a.query == 'What you're querying for' AND your.b.query == here
...