2009-07-31 9 views
2

私はコードをSQLiteデータベースからCore Dataに移植したときに問題が発生しました。NSPredicateを使用して複数のエンティティでルックアップを実行

私が使用しているデータは既存のデータベースから来ており、すべてのテーブル(またはコアデータを使用しているエンティティ)の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 == '%@' 

次に別の検索を実行するo n返されたデータを使用したデータ:

Zones.ID == TecAccessPoints.ZoneID 

など、必要なすべての結果が得られるまではどうですか?

おかげ

ジェームズ

答えて

2

一度に1つのエンティティのみを取り出すことができますので、あなたは、コアデータ述語としてクエリを複製することはできません。しかし、これは、データベーステーブルではなくオブジェクトグラフがもっと有益なものであると考えることがあります。あなたは関係

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

を持っている場合は、例えば、コード内の関係をたどるその後、上記示したよう簡単TecAccessPointsを照会することができます関係を想定し

TecAccessPoint *tap; 
// fetch tap 

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

zonebuildingroomsを、命名され、あなたはコンパイラが文句を言わないように、関連する@propertiesを定義するための適切なNSManagedObjectカテゴリを持っています。

もちろん、コアデータの下には、複数のテーブルにまたがるJOINという一連のSQLクエリが実行されています。コアデータは、パフォーマンスのヒットを最小限にすることについてはかなり良いですが、DBオタクなら、これはあなたを悩ませるかもしれません。もしそうなら、あなたは生のSQLiteを守らなければならないでしょう。コアデータに移動することは、オブジェクトグラフレベルでのことを考えて、ほとんどの部分の実装の詳細を無視することを意味します。

+0

私が恐れていたことは、現在の関係がテーブルの主キーを使用してマッピングされているときにエンティティ間の関係を作成することです(オブジェクトにリンクする必要があります) - コアデータ将来の開発に参加する人にはわかりやすいコードにする必要がありますが、私はテーブルの結合を実行するのが好きです。私はインポート時にも、すべての関係を作ることで障壁になるでしょうまたは各エンティティを個別に呼び出す必要があるときにクエリで... –

+0

コアデータを含むかどうかに関係なく、データベーススキーマ間の変換には痛みがあります(明らかにハイエンドのデータベースシステムまたはORMはこの痛みを緩和するのに役立ちますが、誰かがそれらをコード化するために苦痛に耐えなければなりません...)。この場合、インポート時にJOINを実行するのが適切な方法です。まず、すべてのクエリではなく、インポート中にコーディング時間(およびランタイムパフォーマンスヒット)を1回取ることができます。第二に、コアデータフレームワークを最大限に活用することができます。 –

+0

このBarryのおかげで、私は現在のSQLiteの実装に固執することに決めました。部分的には2.xで誰も除外しないようにしました。部分的には、インポートコードが肥大化し始めたからです。私が調べてきたもう一つのことは、すべてのエンティティについて、永続的なストアからコアデータがそれを格納し、すべての関係がメモリに格納されていることです。私がロードしたいテーブルの部分。私は中核となるデータブランチを保持していますので、将来私はそれに戻ってくることができます。もう一度ありがとう。 –

関連する問題