2010-01-05 10 views
21

Mam trzy podmioty: EntityA, EntityB i EntityC połączone ze związkami to-many.Jaki jest lepszy sposób na zbudowanie NSPredicate z wieloma głębokimi relacjami?

Patrz schemat na szczegóły:

alt text http://img706.imageshack.us/img706/9974/screenshot20091220at124.png

Na uzyskanie wszystkich instancji, które są uzależnione od EntityA EntityB.name używam orzecznik tak:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY EntityB.name like 'SomeName'"]; 

Jaki powinien być orzeczenie o uzyskanie wszystkie wystąpienia EntityA, które zależą od EntityC.name? Próbowałem zapytanie, takie jak @"ANY EntityB.entitiesC.name like 'SomeName'", ale uzyskać wyjątek "multiple to-many keys not allowed here".

poważaniem,

Victor

Odpowiedz

12

Moim ostatecznym rozwiązaniem jest użycie SUBQUERY.

NSPredicate *p = [NSpredicate predicateWithFormat:@"(name like %@) AND (0 != SUBQUERY(entitiesB, $x, (0 != SUBQUERY($x.entitiesC, $y, $y.name like %@)[email protected]))[email protected])", nameA, nameC]; 

Niestety nie udało się rozwinąć tego zapytania w obiektach nsExpression.

+0

Czy to działa z magazynem SQLite dla systemów Mac OS i iOS? Z dokumentacji Apple (z biblioteki iOS 5.0: Przewodnik programowania danych podstawowych> Funkcje magazynu trwałego> Predykaty pobierania i deskryptory sortowania - mogą się różnić w Mac OS): "Istnieją dodatkowe ograniczenia dotyczące predykatów, których można używać z Sklep SQLite: Nie można tłumaczyć "arbitralnych" zapytań SQL na predykaty. " – Dalmazio

+0

Nie testowałem tego w systemie Mac OS, ale dla iOS jego praca jest w porządku. – Victor

2

Chociaż został zatrzymany w następującej decyzji:

pierwsze, uzyskać wszystkie EntityC które spełniają warunek EntityC.name równy 'somename'

NSPredicate *p = [NSPredicate predicateWithFormat:@"name like %@", @"SomeName]; 

...

NSArray *res = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

Potem dostać tablicę EntityB z góry zapytania

NSArray *parentBs = [res valueForKeyPath:@"@distinctUnionOfObjects.parent"]; 

Niż dostać tablicę EntityB spełniających EntityB.EntitiesC.name warunek równego „somename”:

NSExpression *leftExpression = [NSExpression expressionForEvaluatedObject]; 
NSExpression *rightExpression = [NSExpression expressionForConstantValue:parentBs]; 

NSPredicate *p = [NSComparisonPredicate predicateWithLeftExpression:leftExpression rightExpression: rightExpression modifier:NSDirectPredicateModifier type:NSInPredicateOperatorType options:0]; 

Powtarzam to samo dla EntityA.

Skuteczność tego rozwiązania jest wątpliwa i nadal oczekuję lepszego rozwiązania tego problemu.

Powiązane problemy