核心数据按祖父母实体关系过滤

时间:2016-04-06 13:48:31

标签: ios core-data nspredicate nsfetchrequest

我有三个这样的实体: 发布者< -------->>作者< -------->>书

Publisher{
    id = <uniqueId>
    authors -->> Author
}
Author{
    id = <uniqueId>
    books -->> Book //ordered relationship
    publisher --> Publisher
}
Book{
    info = <string_with_info>
    author --> Author
}

我想按作者ID和发布商ID过滤所有图书并获取其信息属性。有些东西:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"author.publisher.id == %@ AND author.id == %@", publisherId, authorId];
[request setPredicate:predicate];
[request setEntity:[NSEntityDescription entityForName:@"Book" inManagedObjectContext:managedContext]];
[request setResultType:NSDictionaryResultType];
[request setReturnsDistinctResults:YES];
[request setPropertiesToFetch:@[@"info"]];


 NSError *error = nil;
 NSArray *results = [managedContext executeFetchRequest:request error:&error];

其中结果应包含许多带书籍信息的字符串。 我不确定author.publisher.id == %@部分是否有效。

我可以获得作者,然后获得一个包含图书实体的MutableSet。从那里我可以循环它们并将它们的信息推送到一个新的数组。这样做的工作,但我想做同样的事情,如果可能只有一个提取。

编辑:有效的解决方案是更改谓词,如下所示:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(0 != SUBQUERY(author, $x, (0 != SUBQUERY($x.publisher, $y, $y.id like %@).@count)).@count) AND author.id  like %@ ", publisherId, authorId];

一些澄清。作者ID与发布者绑定,仅对该发布者唯一。您可以让两位作者具有相同的ID,但发布者不同。

扩展原始问题。订购作者书籍。 results中的信息是否会按照作者订购书籍的顺序排序?根据我的有限测试,答案是肯定的。

Mundi指出了可能的身份冲突,并且已经注意到了。

1 个答案:

答案 0 :(得分:1)

首先,在澄清您的authorID 唯一后,您需要使用原始复合谓词:

NSPredicate(format: "author.publisher = %@ && author.authorID = %@",
  publisher, authorID)
顺便说一下,我会替换你的属性&#34; id&#34;与其他东西,因为有一些潜在的名称冲突&#34; id&#34;。

但是你只能获取作者,使谓词更简洁:

NSPredicate(format: "publisher = %@ && authorID = %@", publisher, authorID)

其次,书籍已经是一套,所以不需要得到明显的结果。实际上,如果您有作者对象,则可以在没有显式提取的情况下执行此操作。

author.books.map { $0.info }

就是你所需要的。看看斯威夫特有多优雅!