Abfragen aller Objekte mehrerer untergeordneter Entitätstypen in Core Data

8

Gegeben das folgende erfundene Beispiel:

Ich möchte meine Daten für alle Objekte abfragen, die entweder Katzen oder Hunde sind. Ich möchte das Ergebnis sortiert nach Namen, unabhängig von der Art, so dass alle Katzen holen und dann alle Hunde holen nicht tun. Ich möchte dies in einer einzigen Abfrage tun.

Eine Möglichkeit wäre, ein PetType-Feld zu Pet hinzuzufügen, jedem Datensatz einen petType-Wert zu geben, der die zugehörige Unterentität identifiziert, und dann wie folgt abzufragen:

%Vor%

Aber der bloße Gedanke, es so zu machen, lässt mich schaudern. Gibt es einen besseren Weg?

Update : Vielen Dank an alle, die geantwortet haben - es gibt einige wirklich gute, durchdachte Lösungen hier und ich schätze sie alle.

Um dies zu verdeutlichen, ist das reale Datenmodell etwas komplexer (nicht immer), aber es ist ziemlich gut organisiert. Ich habe in meiner Zeit mehr als meinen gerechten Anteil an Datenschemata entworfen, und ich bin froh, dass die Entitäten und ihre Beziehungen gut durchdacht sind. Dieses Problem ist entstanden, weil (um das bereits wackelige erfundene Beispiel zu erweitern) der ursprünglich gewünschte Client:

  • eine Ansicht mit einer Liste aller Haustiere
  • eine Ansicht mit einer Liste von Goldfischen
  • eine Ansicht mit einer Liste von Katzen
  • eine Ansicht mit einer Liste von Hunden

So weit, so gut. Aber sie wollen auch eine Ansicht, die eine kombinierte Liste aller Katzen und Hunde zeigt, "weil kleine Mädchen wie Katzen und Hunde mögen". (Am Anfang waren es Katzen und Goldfische, aus dem gleichen Grund.) Es gibt nicht wirklich eine Möglichkeit, diese Teilmenge der konkreten Entitäten auf natürliche Weise zu gruppieren; es ist wirklich ziemlich willkürlich.

Bis jetzt scheint Dave Dribins Ansatz der "abstrakten Zwischeneinheit" die sauberste Lösung zu sein, obwohl ich denke, dass es sich irgendwie künstlich anfühlen würde; wirklich die einzige Art und Weise, wie du die dazwischenliegende Entität wahrheitsgemäß bezeichnen könntest, wäre "ThingLittleGirlsLike"! :)

    
Simon Whitaker 30.06.2011, 05:32
quelle

4 Antworten

3

Wie Sie herausgefunden haben, können Sie entity.name nicht in Ihrem Abrufprädikat für SQLite-Speicher verwenden (Sie können es für andere Geschäftstypen verwenden). Sie können ein petType hinzufügen, wie Sie vorschlagen, was gut genug funktioniert, aber mich auch schaudern lässt. Alternativ können Sie alle Pets abrufen und dann die abgerufenen Ergebnisse basierend auf entity.name filtern. Aber das ist ein wenig ineffizient, da Sie mehr Entitäten laden, als Sie benötigen, und Ihre In-Memory-Filterung, die SQLite in Ihrem Namen tun könnte.

Ich denke, die wirkliche Frage ist: Was versuchst du zu tun? Wenn Sie wirklich Cats und Dogs ohne Goldfish holen müssen, sollte Ihr Modell das widerspiegeln. Sie könnten eine FourLeggedPet abstrakte Entität als übergeordnetes Element von Cat und Dog einfügen. Verwenden Sie dann in Ihrer Abrufanforderung FourLeggedPet als Entität mit setIncludesSubentities:YES .

    
Dave Dribin 30.06.2011, 15:30
quelle
2

Ihre verwalteten Objekte haben bereits eine Haustierart: Sie haben ihre entity.name . Wenn du nach allen Pet -Entitäten suchst, die den Entitätsnamen @"Cat" oder @"Dog" haben, sollte das, denke ich.

Beispiel (schnell und schmutzig in Xcode eingegeben, so schlecht gestaltet):

%Vor%

Dies protokolliert Folgendes:

  

2011-06-30 14: 46: 57.435   CDSubentityTest [5626: 407] Entitäten: (       "(Entität: Katze; ID: 0x10025f740    ; Daten: {\ n Name = Fäustlinge; \ n}) ",       "(Einheit: Hund; ID: 0x1002914e0    ; Daten: {\ n Name = Rover; \ n}) ")

Beachten Sie das erwartete Verschwinden des Goldfisches.

    
user23743 30.06.2011 13:04
quelle
0

Ich glaube, der von Ihnen vorgeschlagene Ansatz würde gut funktionieren. Mit petType können Sie auch Subtypen von Pet s definieren (d. H. "Säugetiere", "Vögel", "Reptilien", "Fische" usw.). Natürlich könntest du stattdessen abstrakte Entitäten für jeden von diesen haben, aber es ist nicht klar, wie du davon auch profitieren würdest. Es hängt letztlich davon ab, wie Ihre Anwendung das Modell verwendet. Müssen Sie jemals alle Pet s holen? Planen Sie die Möglichkeit, nur Cat s und Fish in einem einzigen Abruf zu erhalten? Möchten Sie Daten abrufen, die Sie nicht sofort verwenden?

Sobald Sie die erforderlichen Klassifizierungen basierend darauf definiert haben, wie Sie die Daten anzeigen / verwenden möchten, passen Sie das Modell an diese Klassifikationen an. Ein gutaussehendes, generisches Modell zu haben, kann oft ein Schmerz im Hintern sein, um es zu benutzen ...

    
octy 30.06.2011 14:41
quelle
0

Prädikate erkennen Entitäten nicht, sodass Sie kein Prädikat konstruieren können, um sie zu finden. (Update: Dies gilt nur für SQL-Stores.)

Wenn Sie Ihr Herz auf das Holen nach Haustierart eingestellt haben, haben Sie keine andere Wahl als ein Attribut anzugeben, das den Wert des Haustiertyps liefert und Prädikate und Fetches funktionieren lässt. Sie können jedoch eine wesentlich sauberere und sicherere Version als die von Ihnen vorgeschlagene Version erstellen.

  1. Erstellen Sie für jede Entität ein petType -Attribut (es kann nicht in der Entität geerbt werden, kann aber in benutzerdefinierten NSManagedObject-Unterklassen vererbt werden.)
  2. Setzen Sie dann den Standardwert im Datenmodelleditor auf den Namen von Spezies, z. Katze, Hund, Goldfisch usw. (Wenn Sie ein geerbtes Attribut verwenden, erben Sie auch den Standardwert.)
  3. Überschreiben Sie die Setter-Methode, um nichts effektiv zu machen, wodurch das Attribut nur gelesen wird. (Dies kann von einer gemeinsamen Oberklasse geerbt werden.)

    %Vor%

Um nun alle Hunde und Katzen zu finden, müssen Sie nur noch die fetch-Entity auf Pet setzen und dann ein Array von Pet-Type-Namen für den Operator IN angeben.

%Vor%

Während das funktioniert, denke ich, dass Dave Dribin machte den besten Punkt. Diese Art von Hack wird normalerweise benötigt, wenn Sie Ihr Datenmodell nicht richtig verfeinert haben. Wenn Sie verschiedene Haustiere nach Haustier-Typ gruppieren müssen, dann gehört diese Gruppierung wahrscheinlich zu einem anderen realen Objekt, Zustand oder Ereignis, z. Besitzer, der wiederum mit Beziehungen zu bestimmten Pet-Instanzen modelliert werden sollte. Wenn Sie das tun, geschieht Ihre Gruppierung automatisch und Sie müssen nicht mit all dem herumspielen.

    
TechZen 30.06.2011 16:18
quelle

Tags und Links