2010-09-27 10 views
6

Wiem, że Core Data nie jest bazą danych i istnieje wiele różnic. Czy to ten?Dane podstawowe: 3 sprzężenia stołowe?

w bazie danych, to bym powszechnie mają następujące

A - B >> - >> C

"A" ma wiele "B", który ma wiele "C"

zapytanie „Daj mi wszystko, które zostały c.attr =«x»jest łatwo napisane tak:

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

W danych Core, chciałbym zrobić to samo, ale przy użyciu predykat jak:

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

Rozwiązanie to powoduje błąd: „NSInvalidArgumentException”, powód: "stwardnienie do wielu klawiszy niedozwolone oto

mam rację w interpretacji oznaczać istnieje ograniczenie co Bazy połączenia konferencyjnego -table joins?

Przeszukałem go i nie mogłem znaleźć ostatecznej odpowiedzi.

Moje obecne rozwiązanie tego zapytania wygląda następująco:

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 

Czy istnieje lepszy sposób? Z góry dziękuję za uwagę.

+0

ugh, składnia a, b, c join jest zła. –

Odpowiedz

8

Wychodzisz od tyłu.

Po pierwsze, nie potrzebujesz identyfikatorów dowiązania w danych podstawowych, ponieważ wszystkie powiązane obiekty są już powiązane relacją. Oznacza to, że konstrukcje takie jak where a.id = b.aid and b.id = c.bid nie są w ogóle potrzebne.

Po drugie, zazwyczaj ustawia się jednostkę pobierania dla jednostki, która otrzymuje test definiujący. W tym przypadku, to jest c.attr="X" Więc ustawić pobierał podmiot do C a orzecznik powinien wyglądać mniej więcej tak:

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

to będzie zwracać tablicę wszystkie instancje C które spełniają test. Następnie znalezienie dowolnego konkretnego B lub A jest tylko kwestią chodzenia relacji dla każdego C.

Jeśli odwrotna zależność jest jednym np < - >> B < - >> C, to po prostu poprosić każdego C dla wartości b.a tak:

AObject *anA = aCinstance.b.a; 

Ważne jest, aby pamiętać, nie zajmujesz się tutaj tabelami. Masz do czynienia z wykresem obiektów. Ustawiasz pobieranie do określonej jednostki, a następnie chodzisz relacjami filtrowanych podmiotów.

+0

To pomaga. Dzięki! – Mike

1

Czy dane podstawowe mogą dodawać testy dla atrybutów b i a? Czy będę musiał kolejno powtarzać każdy zestaw wyników, aby uzyskać końcowy wynik?

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' 
Powiązane problemy