2009-07-31 16 views
2

Ich habe ein Problem festgestellt, als ich meinen Code von einer SQLite-Datenbank auf Core Data portiert habe.Suche nach mehreren Entitäten mit NSPredicate

Die Daten, die ich verwende, stammen aus einer vorhandenen Datenbank und haben als solche alle Beziehungen, die unter Verwendung der ID jeder der Tabellen (oder der Entitäten, die ich jetzt Core Data verwende) definiert sind. Mein Problem ist, dass ich gegen eine einzelne Tabelle abfragen und dann dieses Ergebnis verwenden möchte, um durch die Daten fortzuschreiten, um alle anderen Daten zu erhalten, die ich benötige.

Die Original-Datenbank wie folgt aussieht:

CREATE TABLE TecAccessPoints (MAC varchar NOT NULL PRIMARY KEY UNIQUE,ZoneID integer NOT NULL,Floor integer); 
CREATE TABLE Zones (ID integer NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,ZoneName varchar NOT NULL,BuildingID integer,ZoneDescription varchar); 
CREATE TABLE Buildings (ID integer NOT NULL PRIMARY KEY AUTOINCREMENT,BuildingName varchar NOT NULL,CampusID integer NOT NULL,BuildingDescription varchar,Long float,Lat float); 
CREATE TABLE Campuses (ID integer NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,CampusName varchar NOT NULL,CampusDescription text, Latitude float, Longitude float); 

Meine ursprüngliche SQL-Abfrage ist:

SELECT DISTINCT Zones.ID, Zones.ZoneName, Buildings.ID, Buildings.BuildingName, Campuses.ID, Campuses.CampusName, Rooms.ID, Rooms.NameNumber, Rooms.Floor 
FROM Zones, TecAccessPoints, Buildings, Campuses, Rooms 
WHERE Campuses.ID = Buildings.CampusID 
    AND Buildings.ID = Zones.BuildingID 
    AND Zones.ID = Rooms.ZoneID 
    AND Zones.ID = TecAccessPoints.ZoneID 
    AND TecAccessPoints.MAC = '%@'; 

Gibt es eine Möglichkeit, dass ich diese Abfrage mit NSPredicate replizieren kann (oder so ähnlich), oder es ist der Fall, dass ich zuerst die Suche durchführen muss

TecAccessPoints.MAC == '%@' 

Dann tun Sie eine andere Suche o n die Daten mit den zurückgegebenen Daten wie:

Zones.ID == TecAccessPoints.ZoneID 

Und so weiter, bis ich alle meine Ergebnisse habe, die ich brauche?

Dank

James

Antwort

2

Sie können Ihre Abfrage als Core Data Prädikat nicht replizieren, weil Sie nur eine Einheit zu einem Zeitpunkt abrufen kann. Dies kann jedoch ein Fall sein, in dem das Nachdenken über Dinge wie das Objektdiagramm eher als die Datenbanktabellen viel fruchtbarer sein könnte. Wenn Sie Beziehungen

TecAccessPoints <*-> Zones <*-> Buildings <-> etc. 
          <-*> Rooms 

können Sie leicht TecAccessPoints abfragen, wie Sie oben dann zeigen die Beziehungen im Code folgen, z.B.

TecAccessPoint *tap; 
// fetch tap 

Campus *campus = tap.zone.building.campus; 
NSSet *rooms = tap.zone.rooms; 

die Beziehungen angenommen werden zone genannt, building, rooms usw., und Sie haben entsprechende NSManagedObject Kategorien der @properties so verbunden zu definieren, dass der Compiler beschwert sich nicht.

Natürlich unter Core Data macht eine Sequenz von SQL-Abfragen, die jeweils ein JOIN über mehrere Tabellen sind. Core Data ist ziemlich gut darin, die Performance so minimal zu halten, aber wenn du ein DB-Geek bist, könnte dich das stören. Wenn dies der Fall ist, müssen Sie bei der rohen SQLite bleiben. Wenn Sie zu Core Data wechseln, sind Sie bereit, über Dinge auf der Ebene des Objektdiagramms nachzudenken und die Implementierungsdetails größtenteils zu ignorieren.

+0

Das war, was ich hatte Angst - machen die Beziehungen zwischen den Entitäten (die es mit einem Objekt verknüpft werden müssen), wenn die aktuellen Beziehungen zugeordnet sind mit den Primärschlüsseln in der Tabelle - Ich bin daran interessiert, Core Data zu verwenden weil es * meinen Code für zukünftige Entwickler einfacher verständlich machen sollte, aber ich mag die Möglichkeit, Joins auf Tabellen durchzuführen ... Ich schätze, ich werde beim Import eine Barriere überwinden, indem ich alle Beziehungen herstelle oder bei der Abfrage, wenn ich jede Entität einzeln aufrufen muss ... –

+0

Wie Sie sagen, muss es beim Übersetzen zwischen Datenbankschemata etwas Mühe geben, unabhängig davon, ob Sie Kerndaten verwenden oder nicht (offensichtlich High-End-Datenbanksysteme oder ORMs) helfen, diesen Schmerz zu mildern, aber jemand musste den Schmerz aushalten, um sie zu kodieren ...). In diesem Fall ist das Ausführen der JOINs beim Import der richtige Weg.Zuallererst können Sie die Codierungszeit (und den Laufzeitleistungstreffer) einmal während des Imports und nicht bei jeder Abfrage nehmen. Zweitens können Sie das Kerndaten-Framework in vollem Umfang nutzen. –

+0

Vielen Dank für Ihre Hilfe bei diesem Barry, ich habe mich entschieden, bei der aktuellen SQLite-Implementierung zu bleiben - teilweise schließe ich niemanden auf 2.x aus und teilweise weil mein Import-Code anfing, etwas aufgebläht zu werden. Die andere Sache, die ich gesehen habe, während ich das untersucht habe, ist, dass ich für jede Entität, die ich aus dem persistenten Speicher erhalte, die Kerndaten und ALLE ihre Beziehungen in den Speicher lege, wo ich wie bei der SQL-Abfrage auswählen kann Teile von welchen Tabellen möchte ich laden. Ich habe einen Kerndatenzweig behalten, damit ich in Zukunft darauf zurückkommen kann. Noch einmal Danke. –

Verwandte Themen