(前回)Cocoaの日々: CoreData - リレーションシップ(3) 多対多のモデリング
今回はタグを使った検索を行ってみる。といってもエントリの検索と全く同じ。
- (void)fetchDataByTag
{
NSManagedObjectContext* moc = [self managedObjectContext];
NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Tag"
inManagedObjectContext:managedObjectContext]];
NSError* error = nil;
NSLog(@"----- executeFetchRequest ------------------------------------------");
NSArray* tags = [moc executeFetchRequest:request error:&error];
NSLog(@"----- listup entry ---------------------------------------------------");
for (Tag* tag in tags) {
NSLog(@"tag name=%@", tag.name);
for (BlogEntry* entry in tag.entries) {
NSLog(@"*entry*: %@", entry.title);
}
}
[request release];
}
結果
[16229:10b] ----- executeFetchRequest ------------------------------------------ [16229:10b] ----- listup entry --------------------------------------------------- [16229:10b] tag name=Mac [16229:10b] *entry*: CoreData のリレーションしっぷについて [16229:10b] tag name=iPad [16229:10b] *entry*: iPad 5/28発売 [16229:10b] *entry*: CoreData のリレーションしっぷについて [16229:10b] tag name=iPhone [16229:10b] *entry*: CoreData のリレーションしっぷについて
発行している SQLをチェックしてみる。
[16245:10b] CoreData: sql: pragma cache_size=1000 16245:10b] ----- executeFetchRequest ------------------------------------------ [16245:10b] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME FROM ZTAG t0 [16245:10b] CoreData: annotation: sql connection fetch time: 0.0682s [16245:10b] CoreData: annotation: total fetch execution time: 0.0752s for 3 rows. [16245:10b] ----- listup entry --------------------------------------------------- [16245:10b] tag name=Mac [16245:10b] CoreData: sql: SELECT 0, t0.Z_PK FROM Z_1TAGS t1 JOIN ZBLOGENTRY t0 ON t0.Z_PK = t1.Z_1ENTRIES WHERE t1.Z_2TAGS = ? ...(1) [16245:10b] CoreData: annotation: sql connection fetch time: 0.0054s [16245:10b] CoreData: annotation: total fetch execution time: 0.0102s for 1 rows. [16245:10b] CoreData: annotation: to-many relationship fault "entries" for objectID 0x1715a0 <x-coredata://C7F5193B-3731-4955-8F11-51453ABAAC99/Tag/p1> fulfilled from database. Got 1 rows ...(2) [16245:10b] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZTITLE, t0.ZCONTENT, t0.ZCREATED FROM ZBLOGENTRY t0 WHERE t0.Z_PK = ? ...(3) [16245:10b] CoreData: annotation: sql connection fetch time: 0.0043s [16245:10b] CoreData: annotation: total fetch execution time: 0.0079s for 1 rows. [16245:10b] CoreData: annotation: fault fulfilled from database for : 0x173270 <x-coredata://C7F5193B-3731-4955-8F11-51453ABAAC99/BlogEntry/p2>[16245:10b] *entry*: CoreData のリレーションしっぷについて : :
ポイントとなる箇所の色を変えてある。
(1) まず中間テーブル Z_1TAGS からエントリのプライマリキーにあたるカラム値(Z_PK)を取得する。
(2) 続いて、Z_PKに対応するオブジェクトの状態が fault なので、DBへフェッチしにいく。
(3) (1)で取得した Z_PK(複数)の値を条件に ZBLOGENTRY からデータを取得し有効な BlogEntry のインスタンスを用意する。
ソース:
CoreDataRelationship at 2010-05-20 from xcatsan's SampleCode - GitHub
- - - -
RDB しか経験が無いので、ついつい SQLite のスキーマを確認してしまった。ただそのおかげで徐々にモデリングのイメージがつかめてきた。