Выполнение поиска по нескольким объектам с использованием NSPredicate
-
06-07-2019 - |
Вопрос
Я столкнулся с проблемой, когда переносил свой код из базы данных 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
И так далее, пока я не получу все нужные мне результаты?
Спасибо
Джеймс
Решение
Вы не можете реплицировать свой запрос в качестве основного предиката данных, поскольку одновременно вы можете извлекать только один объект.Однако это может быть тот случай, когда гораздо более плодотворным может оказаться представление о вещах как о графе объектов, а не как о таблицах базы данных.Если у вас есть отношения
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-запросов, каждый из которых представляет собой объединение нескольких таблиц.Core Data неплохо справляется с тем, чтобы добиться минимального снижения производительности, но если вы специалист по базам данных, это может вас беспокоить.Если это так, вам придется придерживаться необработанного SQLite.Переход к Core Data подразумевает, что вы готовы думать о вещах на уровне объектного графика и по большей части игнорировать детали реализации.