Realizar búsquedas en múltiples entidades usando NSPredicate
-
06-07-2019 - |
Pregunta
Me he encontrado con un problema al portar mi código desde una base de datos SQLite a Core Data.
Los datos que estoy usando provienen de una base de datos existente y, como tal, tienen todas las relaciones definidas usando el ID de cada una de las tablas (o entidades ahora que estoy usando Core Data). Mi problema es que quiero consultar una sola tabla y luego usar ese resultado para propagarme a través de los datos para obtener todos los demás datos que necesito.
La base de datos original se ve así:
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);
Mi consulta SQL original es:
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 = '%@';
¿Hay alguna forma de replicar esta consulta usando NSPredicate (o algo similar) o es el caso de que primero tenga que realizar la búsqueda?
TecAccessPoints.MAC == '%@'
Luego haga otra búsqueda en los datos usando los datos devueltos como:
Zones.ID == TecAccessPoints.ZoneID
¿Y así hasta que tenga todos los resultados que necesito?
Gracias
James
Solución
No puede replicar su consulta como un predicado de Core Data porque puede buscar solo una entidad a la vez. Sin embargo, este puede ser un caso en el que pensar en cosas como el gráfico de objetos en lugar de las tablas de la base de datos podría ser mucho más fructífero. Si tienes relaciones
TecAccessPoints <*-> Zones <*-> Buildings <-> etc.
<-*> Rooms
Puede consultar fácilmente TecAccessPoints como se muestra arriba y luego seguir las relaciones en el código, por ejemplo,
TecAccessPoint *tap;
// fetch tap
Campus *campus = tap.zone.building.campus;
NSSet *rooms = tap.zone.rooms;
suponiendo que las relaciones se denominan zone
, building
, rooms
, etc. y tiene las categorías apropiadas de NSManagedObject
para definir el @properties
asociado para que el compilador no se queje.
Por supuesto, debajo de Core Data está haciendo una secuencia de consultas SQL, cada una unida en varias tablas. Core Data es bastante bueno para hacer que el rendimiento sea mínimo, pero si eres un geek de DB, esto puede molestarte. Si es así, tendrás que seguir con el SQLite sin procesar. Pasar a Core Data implica que está dispuesto a pensar en cosas a nivel de gráfico de objetos e ignorar los detalles de implementación en su mayor parte.