【问题标题】: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 冲突,并已记录。

【问题讨论】:

    标签: ios core-data nspredicate nsfetchrequest


    【解决方案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 来过滤。谢谢你的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多