Выполнение поиска по нескольким объектам с использованием NSPredicate - PullRequest
2 голосов
/ 31 июля 2009

Я столкнулся с проблемой, когда переносил свой код из базы данных SQLite в Core Data.

Данные, которые я использую, поступают из существующей базы данных и поэтому имеют все отношения, определенные с использованием идентификатора каждой из таблиц (или объектов, которые я сейчас использую Core Data). Моя проблема в том, что я хочу выполнить запрос к одной таблице, а затем использовать этот результат для распространения данных, чтобы получить все остальные данные, которые мне нужны.

Исходная база данных выглядит так:

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

Мой оригинальный запрос SQL:

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

Есть ли способ, которым я могу повторить этот запрос, используя NSPredicate (или что-то подобное), или это тот случай, когда мне придется сначала выполнить поиск

TecAccessPoints.MAC == '%@'

Затем выполните другой поиск данных, используя возвращенные данные, например:

Zones.ID == TecAccessPoints.ZoneID

И так до тех пор, пока у меня не будут все мои результаты, которые мне нужны?

Спасибо

Джеймс

1 Ответ

2 голосов
/ 31 июля 2009

Вы не можете реплицировать свой запрос как предикат Core Data, потому что вы можете выбрать только одну сущность за один раз.Тем не менее, это может быть случай, когда размышления о вещах как об объектном графе, а не о таблицах базы данных, могут быть гораздо более плодотворными.Если у вас есть отношения

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

Вы можете легко запрашивать TecAccessPoints, как показано выше, а затем следовать отношениям в коде, например,

TecAccessPoint *tap;
// fetch tap

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

, предполагая, что отношения называются zone, building, rooms и т. Д., И у вас есть соответствующие категории NSManagedObject, чтобы определить связанный @properties, чтобы компилятор не жаловался.

Конечно, под Core Data выполняется последовательность SQL-запросов, каждый из которых является JOIN для нескольких таблиц.Core Data неплохо справляется с минимальной производительностью, но если вы фанат БД, это может вас беспокоить.Если это так, вам придется придерживаться необработанного SQLite.Переход к базовым данным подразумевает, что вы готовы думать о вещах на уровне графов объектов и игнорировать детали реализации по большей части.

...