2010-09-27 16 views
6

Ich weiß, Core Data ist keine Datenbank und es gibt viele Unterschiede. Ist dieser?Kerndaten: 3 Tabelle beitreten?

In einer Datenbank, würde ich häufig die folgenden

A haben - >> B - >> C

"A" hat viele "B", die viele "C" hat

Die Abfrage: „Gib mir alle A ist die =‚X‘c.attr haben, ist leicht geschrieben wie:

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

In Core Data, ich möchte das gleiche tun, sondern mit einem Prädikat wie:

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

dies tun führt zu dem Fehler: ‚NSInvalidArgumentException‘, Grund: ‚mehrere zu viele Schlüssel sind hier nicht erlaubt‘

Bin ich richtig eine Einschränkung zu bedeuten, zu interpretieren ist auf welche Datenbanken Multi nennen -table verbindet?

Ich googelte herum und konnte keine definitive Antwort finden.

Meine aktuelle Lösung auf diese Frage wie folgt aussieht:

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 

Gibt es einen besseren Weg? Danke im voraus für die Überlegung.

+0

ugh, die a, b, c Join-Syntax ist böse. –

Antwort

8

Sie gehen rückwärts davon.

Zunächst benötigen Sie die Verknüpfungs-IDs in den Stammdaten nicht, da alle verwandten Objekte bereits durch die Beziehung verknüpft sind. Dies bedeutet, dass Konstruktionen wie where a.id = b.aid and b.id = c.bid überhaupt nicht benötigt werden.

Zweitens legen Sie im Allgemeinen die Fetch-Entität für die Entität fest, die den Definitionstest empfängt. In diesem Fall ist, dass c.attr="X" So setzen Sie Ihr Unternehmen zu C holen und Ihr Prädikat aussehen sollte etwas:

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

zurückkehren wird dies ein Array, das alle C Instanzen, die den Test erfüllen. Dann nur eine bestimmte B oder A zu finden ist nur eine Frage des Gehens die Beziehung für jeden C.

Wenn Ihre inverse Beziehung zu-Eins zB A < - >> B < - >> C, fragen die Sie gerade jeden C für den Wert der b.a so:

AObject *anA = aCinstance.b.a; 

Es ist wichtig, daran zu erinnern, Sie haben es hier nicht mit Tabellen zu tun. Sie haben es mit einem Objektgraphen zu tun. Sie legen den Abruf auf eine bestimmte Entität fest und führen dann die Beziehungen der gefilterten Entitäten durch.

+0

Das hilft. Vielen Dank! – Mike

1

Ist es für Kerndaten möglich, Tests für Attribute von b und a hinzuzufügen? Oder muss ich jedes Ergebnis nacheinander durchlaufen, um mein Endergebnis zu erhalten?

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' 
Verwandte Themen