按祖父母实体关系过滤核心数据
Posted
技术标签:
【中文标题】按祖父母实体关系过滤核心数据【英文标题】:Core Data filter by grandparent entity relationship 【发布时间】:2016-04-06 13:48:30 【问题描述】:我有三个这样的实体: 出版商 > 作者 > 书籍
Publisher
id = <uniqueId>
authors -->> Author
Author
id = <uniqueId>
books -->> Book //ordered relationship
publisher --> Publisher
Book
info = <string_with_info>
author --> Author
我想按 Author id 和 Publisher id 过滤所有书籍并获取它们的 info 属性。类似于:
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。从那里我可以遍历它们并将它们的信息推送到一个新数组。这可以完成这项工作,但如果可能的话,我想只用一个 fetch 来做同样的事情。
编辑:一个可行的解决方案是像这样改变谓词:
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 已指出可能的 id 冲突,并已记录。
【问题讨论】:
【参考方案1】:首先,在澄清您的 authorID 不是唯一之后,您需要使用您原来的复合谓词:
NSPredicate(format: "author.publisher = %@ && author.authorID = %@",
publisher, authorID)
顺便说一句,我会将您的属性“id”替换为其他内容,因为与“id”存在一些潜在的名称冲突。
但是只能获取作者,使得谓词更简洁:
NSPredicate(format: "publisher = %@ && authorID = %@", publisher, authorID)
其次,books 已经是一个集合,所以不需要得到不同的结果。实际上,如果您有作者对象,您可以在没有显式获取的情况下执行此操作。
author.books.map $0.info
就是你所需要的。看看 Swift 是多么优雅!
【讨论】:
作者 ID 与发布者相关联。可能有第二个出版商,其作者与另一个出版商的另一个作者具有相同的 id。在问题中没有正确解释是我的错误。感谢您指出可能的 id 冲突。会解决的。 那么逻辑仍然成立。 Core Data 并不关心这些作者 ID 是什么——框架通过关系维护自己的 ID。 恐怕我听不懂。您不是在过滤所有可以说 authorID = 1 的书籍。我们在两个出版商中有这样的 authorID。因此,您的谓词获得 PublisherOne->AuthorOne,authorID = 1->books 和 PublisherTwo->AuthorTwo,authorID = 1->books。现在你有了两个作者的书的结果。 您的 authorID 不是唯一的。因此,它们不是主键,也不会在其他表中用作外键。它们只是一些属性。让关系管理这些细节——这就是 Core Data 的用途。我将更改谓词以反映这一点。 好的,我相信我现在理解你了。但是我确实想使用它们以及 profileID 来过滤。谢谢你的解释。以上是关于按祖父母实体关系过滤核心数据的主要内容,如果未能解决你的问题,请参考以下文章