2009-07-31 4 views
2

J'ai rencontré un problème lors du transfert de mon code depuis une base de données SQLite vers Core Data.Exécution de la recherche sur plusieurs entités à l'aide de NSPredicate

Les données que j'utilise proviennent d'une base de données existante et ont donc toutes les relations définies en utilisant l'ID de chacune des tables (ou entités maintenant que j'utilise Core Data). Mon problème est que je veux interroger une seule table puis utiliser ce résultat pour propager les données afin d'obtenir toutes les autres données dont j'ai besoin.

La base de données originale ressemble:

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); 

Ma requête SQL originale est:

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 = '%@'; 

Est-il possible que je peux reproduire cette requête en utilisant NSPredicate (ou quelque chose de similaire) ou est-ce le cas que je vais devoir d'abord effectuer la recherche

TecAccessPoints.MAC == '%@' 

Puis faire une autre recherche o n les données utilisant les données retournées comme:

Zones.ID == TecAccessPoints.ZoneID 

Et ainsi de suite jusqu'à ce que j'ai tous mes résultats dont j'ai besoin?

Merci

James

Répondre

2

Vous ne pouvez pas répliquer votre requête comme un prédicat Core Data, car vous pouvez chercher une seule entité à la fois. Cependant, cela peut être un cas où penser à des choses comme le graphique d'objet plutôt que les tables de base de données pourrait être beaucoup plus fructueux. Si vous avez des relations

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

Vous pouvez facilement interroger TecAccessPoints comme vous montrer ci-dessus puis suivez les relations dans le code, par exemple

TecAccessPoint *tap; 
// fetch tap 

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

en supposant que les relations sont nommés zone, building, rooms, etc. et vous avez NSManagedObject appropriés pour définir les catégories les associés @properties de telle sorte que le compilateur ne se plaint pas.

Bien sûr, sous les données de base, une séquence de requêtes SQL est jointe à plusieurs tables. Core Data est assez bon pour faire le coup de performance de ce minimum, mais si vous êtes un geek DB, cela peut vous déranger. Si c'est le cas, vous devrez vous en tenir au SQLite brut. Le passage aux données de base implique que vous êtes prêt à penser à des choses au niveau du graphe d'objet et ignorer les détails de l'implémentation pour la plupart.

+0

C'est ce dont j'avais peur - faire les relations entre les entités (qui nécessitent d'être lié à un objet) lorsque les relations actuelles sont mappées en utilisant les clés primaires dans la table - Je tiens à utiliser Core Data parce que cela * devrait * rendre mon code plus facile à comprendre pour tous ceux qui rejoindront le développement dans le futur mais j'aime la possibilité d'effectuer des jointures sur des tables ... Je suppose que je vais frapper une barrière soit à l'importation en faisant toutes les relations ou sur requête quand je dois appeler chaque entité séparément ... –

+0

Comme vous le dites, il doit être difficile de traduire entre les schémas de base de données, que vous utilisiez ou non des données de base (les systèmes de base de données haut de gamme ou ORM aider à atténuer cette douleur mais quelqu'un a dû endurer la douleur pour les coder ...). Dans ce cas, faire les JOINs à l'importation est la bonne façon de procéder.Tout d'abord, vous pouvez prendre le temps de codage (et l'exécution de performance d'exécution) une fois pendant l'importation plutôt qu'à chaque requête. Deuxièmement, vous pourrez utiliser le framework Core Data à son plein potentiel. –

+0

Merci pour votre aide avec ce Barry, j'ai décidé de m'en tenir à l'implémentation SQLite actuelle - en partie pour ne pas exclure qui que ce soit sur 2.x et en partie parce que mon code d'importation commençait à être un peu gonflé. L'autre chose que j'ai constatée pendant que j'étudiais ceci est que pour chaque entité que je récupère du magasin persistant, les données de base le placent et toutes ses relations en mémoire, où comme avec la requête SQL, je peux sélectionner parties de quelles tables je veux charger. J'ai gardé une branche de données de base pour que je puisse y revenir à l'avenir. Merci encore. –

Questions connexes