2010-09-27 4 views
6

Я знаю, что Core Data не является базой данных, и есть много различий. Это один?Основные данные: 3 таблицы присоединиться?

В базе данных, я бы обычно имею следующий

A - >> B - >> C

"А" имеет много "B", который имеет много "C"

запрос, «Дай мне все а-х, которые c.attr =„X“легко написано как:

select * from a, b, c where a.id = b.aid and b.id = c.bid and c.attr = 'X' 

в основных данных, я хотел бы сделать то же самое, но используя предикат, как:

NSPredicate *predicate = 
    [NSPredicate predicateWithFormat:@"ANY bs.cs.attr = %@", "X"]; 
[frequest setEntity:entityA]; 
[frequest setPredicate:predicate]; 

Делая это приводит к ошибке: «NSInvalidArgumentException», причина: «множественный ко многим ключи не разрешены здесь»

Я правильно интерпретировать в виде есть ограничение на то, что базы данных называют мульти -table присоединяется?

Я googled вокруг и не смог найти окончательный ответ.

Мой текущий решение этого запроса выглядит следующим образом:

NSPredicate *predicate = 
    [NSPredicate predicateWithFormat:@"ANY cs.attr = %@", "X"]; 
... 
NSArray *bs = //execute fetch 
for (B *b in bs) { 
    //add b.a into an array 
} 
//return array 

Есть ли лучший способ? Заранее благодарим за рассмотрение.

+0

ugh, синтаксис a, b, c является злым. –

ответ

8

Ваше намерение об этом обратном.

Прежде всего, вам не нужны идентификаторы ссылок в Core Data, потому что все связанные объекты уже связаны отношением. Это означает, что конструкции вроде where a.id = b.aid and b.id = c.bid не нужны вообще.

Во-вторых, вы обычно устанавливаете объект выборки для объекта, который получает определяющий тест. В этом случае, то есть c.attr="X" Итак, вы установили выборку объект в C и ваш предикат должен выглядеть примерно так:

NSPredicate *p=[NSPredicate predicateWithFormat:@"attr=%@",xValue]; 

это возвращает массив всех C экземпляров, которые отвечают тест. Затем поиск каких-либо конкретных B или A - это всего лишь вопрос о том, как пройти связь для каждого C.

Если обратная связь является один например < - >> B < - >> С, вы просто попросите каждого C для значения b.a так:

AObject *anA = aCinstance.b.a; 

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

+0

Это помогает. Благодаря! – Mike

1

Возможно ли, чтобы данные ядра добавляли тесты для атрибутов как b, так и a? Или мне придется последовательно перебирать каждый набор результатов, чтобы получить окончательный результат?

select 
    p.id, p.total 
from 
    purcord p, line l, delivery d 
where 
    l.purcord_id = p.id 
    and d.purcord_id = l.purcord_id 
    and d.purcord_line_no = l.line_no 
    and d.status = 'notdelivered' 
    and l.status = 'open' 
    and p.status = 'open' 
Смежные вопросы