Основные объекты выборки данных, которые связаны с другим объектом - PullRequest
14 голосов
/ 17 июля 2009

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

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

Ответы [ 5 ]

6 голосов
/ 17 июля 2009

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

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

5 голосов
/ 13 апреля 2013

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

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];

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

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

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

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

5 голосов
/ 17 июля 2009

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

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

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

2 голосов
/ 19 июля 2009

Я в похожей ситуации.

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

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

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

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

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

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

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

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

0 голосов
/ 30 января 2010

Я тоже в похожей ситуации.

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

Мне нужно использовать NSFetchedREsultsController, поэтому я должен перестроить модель. То, что я сделал, - это сохранил отношение «ко-многим» как строковое свойство и создал предикат «hasParent contains% @».

Урок, который я усвоил, заключается в том, что наличие предиката, пересекающего отношение ко многим, приводит к ОГРОМНОМУ снижению производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...