使用NSPredicate在多个实体上执行查找

时间:2009-07-31 09:22:03

标签: iphone objective-c core-data nspredicate

当我将代码从SQLite数据库移植到Core Data时,我遇到了一个问题。

我正在使用的数据来自现有数据库,因此使用每个表(或现在我正在使用Core Data的实体)的ID定义所有关系。我的问题是,我想查询单个表,然后使用该结果通过数据传播,以获取我需要的所有其他数据。

原始数据库如下所示:

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 个答案:

答案 0 :(得分:2)

您无法将查询复制为Core Data谓词,因为您一次只能获取一个实体。但是,这可能是一种情况,即将事物视为对象图而不是数据库表可能会更有成效。如果你有关系

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

您可以轻松查询上面显示的TecAccessPoints,然后按照代码中的关系进行查询,例如

TecAccessPoint *tap;
// fetch tap

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

假设关系名为zonebuildingrooms等,并且您有适当的NSManagedObject类别来定义关联的@properties,以便编译器不抱怨。

当然,Core Data下面正在执行一系列SQL查询,每个查询都是跨多个表的JOIN。 Core Data非常适合将性能降到最低限度,但如果你是一个数据库极客,这可能会让你烦恼。如果是这样,你将不得不坚持使用原始的SQLite。迁移到核心数据意味着您愿意在对象图级别考虑事物并忽略大部分的实现细节。