2012-10-26 4 views
10

Setup:Wie erstellt man ein Core Data Prädikat, um zu testen, dass eine Relation alle gegebenen Objekte enthält?

Ich habe ein Core Data-Objekt A, das eine zu-viele Beziehung zu B hat. Rufen Sie die Beziehung "Elemente" auf. Also, a.items gibt alle B-s zurück, die mit A verbunden sind.

Jetzt habe ich ein manuell zusammengesetztes NSSet "itemSet" von B Objekten.

Ich möchte folgendes tun:

return all A objects whose "items" relation exactly matches itemSet 

Wie konstruiere ich ein Prädikat für das? Ich habe dies versucht:

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
          @"(ALL items in %@)", itemSet]; 

Aber das gibt mir nur Unsupported predicate (null). Diese

:

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
          @"(items in %@)", itemSet]; 

sagt mir unimplemented SQL generation for predicate. Interessant, aber nicht hilfreich.

Also, was ist der richtige Weg, um die Beziehung mit einem Satz zu filtern?

Antwort

19

könnte folgendes Prädikat arbeiten:

[NSPredicate predicateWithFormat:@"([email protected] == %d) AND (SUBQUERY(items, $x, $x IN %@)[email protected] == %d)", 
         itemSet.count, itemSet, itemSet.count]; 

das Prädikat prüft zunächst, dass die Anzahl der Elemente auf die Größe der gegebenen itemSet gleich ist, und prüft dann, ob die Anzahl der Elemente, die sind Mitglied itemSet ist auch gleich der Größe von itemSet. Wenn beide wahr sind, muss items gleich itemSet sein.

+1

Interessant. Das funktioniert. Wo kann ich mehr über SUBQUERY erfahren? Offizielle Prädikat-Dokumente sind ein bisschen spärlich darauf. – Jaanus

+1

@Jaanus: Ich habe Angst, dass ich keine bessere Referenz habe. Ich habe es hauptsächlich dadurch gelernt, dass ich versucht habe, die Antworten anderer Leute in SO zu verstehen. –

+0

Ich hatte Probleme mit der unzureichenden Verwendung von Klammern. Danke für die Antwort, @MartinR –

0

Haben Sie versucht:

NSPredicate *predicate = [NSPredicate predicateWithFormate:@"items == %@", itemSet]; 

Alternativ können Sie eine Teilmenge mit einem einfacheren Prädikat herausziehen und filtern sie die Außenseite des Antrags holen. d. h.

  1. Legen Sie ein Prädikat für die Anzahl der Elemente in der Beziehung fest, die der Anzahl der Elemente in Ihrem Vergleichssatz entsprechen.
  2. Die Ergebnisse abrufen
  3. Diese Ergebnisse filtern, um nur diejenigen anzuzeigen, in denen die Sätze die gleichen Elemente enthalten.
+0

Ja. Das gibt eine weitere Ausnahme: '*** Beenden App aufgrund der nicht abgefangenen Ausnahme 'NSInvalidArgumentException', Grund: 'to-many Schlüssel hier nicht erlaubt'' – Jaanus

+0

Manuelles Filtern (ersten Abruf nach Anzahl, dann Filter) ist definitiv eine Option, aber erstellt unnötiger CD-Verkehr. Ich frage mich, ob dies mit einem Prädikat überhaupt möglich ist oder nicht. – Jaanus

Verwandte Themen