2009-07-22 10 views
42

Ich habe ein Kerndatenmodell, in dem eine Aufgabenentität eine optionale to-viele Beziehung excludedOccurrences enthält. Eine der Eigenschaften von excludedOccurrences ist start, was ein NSDate-Objekt ist. Die ExcludedOccurrence-Entität hat eine umgekehrte obligatorische Eins-zu-Eins-Beziehung zur Task-Entität.Kerndaten, NSPredate und to-many Schlüssel

Um Aufgaben für einen bestimmten Tag abrufen zu können, muss ich sicherstellen, dass der angegebene Tag nicht als Starteigenschaft einer ExcludedOccurrence-Entität angezeigt wird. Einer der Unter Prädikate ich deshalb zu verwenden, ich versuche, ist

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"(ALL excludedOccurrences.start != %@))", today]; 

wo heute ein NSDate Objekt für heute nur die Tag, Monat und Jahr Komponenten einschließlich. Alle Starteigenschaften für ausgeschlossene Ereignisse enthalten auch nur die Komponenten Tag, Monat und Jahr.

Während dies sollte das Lesen in Ordnung, zumindest in der Dokumentation für Core Data und NSPredicate, erhalte ich die folgende Fehlermeldung:

beenden app aufgrund nicht abgefangene Ausnahme ‚NSInvalidArgumentException‘ Grund: ‚Nicht unterstützte Prädikat

wenn ich das Äquivalent Prädikat

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"!(ANY excludedOccurrences.start == %@))", today]; 

keine Ausnahme wird geworfen verwenden jedoch der Code funktioniert nicht wie erwartet: das Auftreten von heute, die nicht ausgeschlossen werden sollte, wird stattdessen ausgeschlossen.

Ich bin nicht sicher, wie auch für den Fall ExcludedOccurrences testen == null: das folgende Prädikat

NSPredicate *nilPredicate = [NSPredicate predicateWithFormat: @"(excludedOccurrences == nil)"]; 

Ursachen zur Laufzeit der Ausnahme

zu vielen Schlüssel hier nicht erlaubt

Da die excludedOccurrences-Beziehung jedoch optional ist, muss ich auch testen, ob sie null ist.

Wie gehe ich damit um? Vielen Dank im Voraus.

Antwort

28

mit Hilfe von euch allen, ich es endlich geschafft, die richtige Prädikat für mein Szenario zu bestimmen. Es sieht so aus, als würde ein NSDate-Objekt als Double behandelt, aber das Double ist nie etwas wie 3.7, es ist immer wie 3.0 Daher ist das folgende Prädikat richtig funktioniert in meinen Tests.

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"([email protected] == 0 || ([email protected] > 0 && NONE excludedOccurrences.start == %@))",thisDate]; 

wo thisDate ist ein NSDate Objekt enthält nur die Tag, Monat und Jahr Komponenten (wie im Fall der Starteigenschaft der ExcludedOccurrence Einheit

Testing für eine leere Beziehung ist im Grunde getan, um die @count Aggregat-Operator, wie sie von einigen Leuten bei Apple vorgeschlagen.

Wieder, danke für Ihre Hilfe sehr. beobachte ich immer noch, dass die Dokumentation in mehreren fehlerhaft ist Teile (vor allem, wo es sagt, dass ALL gut funktioniert, während es stattdessen überhaupt nicht funktioniert).

108

Um eine leere Beziehung zu testen, vergleichen Sie die Anzahl der to-many Schlüssel mit Null.

[NSPredicate predicateWithFormat:@"[email protected] == 0"]; 

Was Ihre subpredicates, beachten Sie, dass Sie nur entweder den ALL oder ANY Modifikatoren in Ihrem letzten Prädikat haben kann, obwohl Sie auch diesen Modifikator mehrere Male während des Prädikats verwenden können.

Nicht OK: ANY foo.bar = 1 AND ALL foo.baz = 2
OK:ANY foo.bar = 1 AND !(ANY foo.baz != 2)

+0

stürzt Ihre leere Beziehung Lösung für mich. –

+0

Entschuldigung, das Prädikat Format wurde korrigiert. Ich habe nie versucht, meine Vermutung zu testen, als dies veröffentlicht wurde, anscheinend auch niemand. –

+1

Es ist unglaublich, wie lange ich nach einem Eins-zu-vielen-Test für eine leere Beziehung gesucht habe. Schön, dass du es hier gepostet hast! –

8

Also, für eine nicht-leere Beziehung zu testen, das funktioniert tatsächlich:

[NSPredicate predicateWithFormat:@"[email protected] != 0"] 

Die Lösung von Ashley Clark gegeben stürzt für mich „zu viele Schlüssel nicht erlaubt hier“

+0

Ich habe meine Antwort korrigiert, weiß nicht, was ich dachte, als ich das schrieb. Mea culpa. –