Основные данные, получающие объекты, находящиеся в связи с другим объектом

Я хочу получить объекты B, которые имеют отношение to-many с объектом A (т.е. A → > B). У меня уже есть A в памяти. Я знаю, что я мог бы получить NSSet объектов B из A, но было бы лучше сделать запрос выборки объектов B (особенно, если я хочу сортировать разделы по дате в UITableView)?

Как бы я сделал такой запрос, который получает только объекты B, принадлежащие одному объекту A?

Ответы

Ответ 1

Если вы уже имеете экземпляр A, просто получите доступ к связанным экземплярам B через Accessor.

Если вам нужно напрямую получить все B, связанные с конкретным A (в этом случае вы этого не сделаете), вы должны построить запрос на выборку для объекта B с предикатом, основанным на (обратном) отношении От Bs до A. (Специфический синтаксис будет зависеть от имени обратной связи и от того, является ли этот обратный для одного или многих.)

Ответ 2

Вы должны указать обратную связь в классе B, чтобы делать то, что вы просите.

Однако я не уверен, почему вы возражаете (не каламбур), чтобы захватить набор объектов B уже в объекте A. Даже если сами объекты ленивы загружены, поскольку у вас уже есть A в памяти, у меня есть (хотя эксперт должен будет проверить), что было бы более эффективно просто захватить набор из A, чем указать новый NSPredicate, и создать совершенно новую Fetch.

Конечно, "более эффективным" мы говорим миллисекунды, даже на устройстве, столь же медленном, как iPhone. Я бы взял набор из объекта A, потому что синтаксис чище. Тот факт, что он также может быть быстрее, является бонусом.

Ответ 3

Вам нужно использовать предикат с вашим A objectID, например:

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

NSEntityDescription *BEntity = [NSEntityDescription entityForName:@"B" inManagedObjectContext:moc];
[fetchRequest setEntity:BEntity];

NSPredicate *predicate = [NSPredicate 
predicateWithFormat:@"(relationship_to_a = %@)", [yourAInstance objectID]];

[fetchRequest setPredicate:predicate];

где relationship_to_a - это имя отношения к A в вашем управляемом объекте B.

Надеюсь, что это поможет.

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

На самом деле, если вы получите свой экземпляр A, извлекая его, вы можете попробовать установить связьKeyPathsForPrefetching в вашем NSFetchRequest равным YES, а затем все объекты в этом отношении не должны быть ошибками. Но это не сработало для меня, поэтому я застрял в решении "выборки".

Ответ 4

Я в аналогичной ситуации.

Я хочу использовать NSFetchedResultsController для управления B в отношениях между несколькими (A → > B). Теперь один из способов сделать это - построить предикат, подобный приведенному ниже, и применить его к объекту B:

NSPredicate *Predicate = [NSPredicate predicateWithFormat:
                                   @"ANY hasParent.label == 'A'"];

Но это ужасно медленный способ делать вещи, и его следует избегать любой ценой. Я попробовал это на 25 000 объектов, чтобы получить около 300, и он взял симулятор около 15 секунд. Это не закончило бы извлечение на iPhone и несколько раз разбилось.

Другим способом было бы сделать то, что уже было упомянуто, создать NSArray из набора, хранящегося в A, и отсортировать его. Если вы отправите allObjects в набор, вы получите массив обратно. A - это объект NSManagedObject, который был выбран ранее.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
                                   initWithKey:@"Name"
                                   ascending:YES];

NSArray *lotsOfB = [[[A hasRelationsTo]
                   allObjects]
                   sortedArrayUsingDescriptors: sortDescriptors];

Это очень быстро. Отсутствие отставания в симуляторе или на устройстве. Но вы не можете использовать NSFetchedResultsController печальные времена: - (

Надеюсь, что это поможет.

Ответ 5

Я тоже в аналогичной ситуации.

У меня не было так много объектов, как pingbat, но потребовалось 15 секунд для извлечения с помощью "ANY hasParent.label ==" A "

Мне нужно использовать NSFetchedREsultsController, поэтому мне нужно переструктурировать модель. То, что я сделал, состояло в том, чтобы сохранить отношение to-many как свойство строки и построить предикат "hasParent содержит% @".

Урок, который я узнал, состоит в том, что наличие предиката, который имеет поперечное отношение "многие", имеет BIG-производительность.