具有多对多关系的 NSPredicate

Posted

技术标签:

【中文标题】具有多对多关系的 NSPredicate【英文标题】:NSPredicate with to-many relationship 【发布时间】:2013-02-19 21:07:38 【问题描述】:

我有两个模型之间的一对多关系,user <-->> followers,关注者表由userIds 组成。我想发出一个获取请求,让相关用户访问这些userIds。我的谓词目前看起来像这样:

predicate = [NSPredicate predicateWithFormat:@"ANY userId IN %@", self.user.followers];

这会产生 0 个结果。我想知道这个谓词应该是什么样子?

更新

我用于将追随者对象添加到用户的代码(来自 JSON 数据):

+ (void)insertFollowersFromDict:(NSDictionary *)dictionary forUser:(User *)user  inManagedObjectContext:(NSManagedObjectContext*)moc

    NSArray *followers = [dictionary objectForKey:@"data"];

    if (followers.count != 0) 
        NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Follower" inManagedObjectContext:moc];
        for (NSString *followerId in followers) 
            Follower *newFollower = [[Follower alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:moc];
            NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init];
            newFollower.user = [User findUser:[numberFormatter  numberFromString:followingId] inManagedObjectContext:moc];
            [user addFollowersObject:newFollower];
        
    

我用来在表格视图中配置单元格的代码:

// This for some reason always result in the same user. 
Follower *follower = [self.fetchedResultsController objectAtIndexPath:indexPath];
User *cellUser = follower.user;

// Always self.user
cell.text = cellUser.name

------------------------
I Anders               I
------------------------
------------------------
I Anders               I 
------------------------

我不知道为什么会这样。

【问题讨论】:

@flexaddicted 谢谢,是的。另外,看看我的编辑,你认为这可能是相关的吗? 安德斯,抱歉我删除了我的评论。恕我直言,@Levi 的回复是正确的。 需要显示用户名还是关注者名? 我需要显示关注者的名字。 我为你添加了一个编辑。希望清楚。 【参考方案1】:

安德斯,

我将尝试提供一些关于我认为非常适合让您的应用正常运行的模型的详细信息。

首先,您的模型应该如下所示(如您所见,我跳过了属性)。

一个User 链接到零个或多个Followers。

让我知道关于关系的讨论。

followers 是与Follower 实体的一对多关系。是这样设置的。

如您所见,rel 是可选,因为用户不能有任何关注者。删除规则是级联,因为如果您删除用户,其关注者也将被删除。

user 与用户相反。看起来像这样。

这不是可选,因为关注者只能与用户一起存在。这是nullify,因为如果您删除关注者,更改将不会对关联用户产生影响。

注意我根据您提供的规范创建了模型,但我认为它也可以扩展以适应多对多关系。这意味着:不同的用户可以拥有相同的关注者。

现在,如果您针对Follower 创建获取请求,您可以通过以下方式检索属于特定用户的所有关注者。

NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Follower"]
[request setPredicate:[NSPredicate predicateWithFormat:@"user == %@", self.user]];
NSArray* results = // execute the request here

// results will contain the followers for a specific user (i.e. the one you used in the predicate)

希望对您有所帮助。

编辑

NSManagedObject* follower = [followerResults objectAtIndex:[indexPath row]]; // this gives you a follower, put some error control if followerResults has no elements
NSManagedObject* user = [follower objectForKey:@"user"]; // this gives you the user associated to that follower

编辑 2

我不明白你的意思,但行为是正确的,因为你正在使用

cell.text = cellUser.name

通过这种方式,您可以检索与用户关联的名称。 只有一个用户与该组关注者关联

例如用户 Andrew 有零个或多个关注者(Mike、Bob、Todd)。

您使用的获取请求执行以下操作:将用户为 Andrew 的所有关注者提供给我。

如果你想显示关注者变化喜欢

cell.text = follower.name; // if Follower entity has a name attribute

非常非常非常重要

向您的Follower 实体添加一个新属性(不是关系)。将其命名为name 并将其设为NSString 类型。正如您对User 实体所做的那样(我想)。

然后,当您创建一个新的Follower 对象时,您将其设置为

 newFollower.user = // set the user
 newFollower.name = // set the name

我真的建议了解 ATTRIBUTESRELATIONSHIPS 之间的区别。

前者是特定实体的属性(例如姓名、年龄、性别)。后者是实体之间的链接。

【讨论】:

谢谢你和@Levi,我之前错过的事情是它把所有的追随者作为一个集合返回。好而全面的答案!一个相关的问题是,如果我将所有关注者作为一组,我该如何检索正确的用户,例如- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath @Anders 我为你添加了一个编辑。请检查代码,因为我是手写的。如果这个问题(或李维斯的问题)完成了您对场景的理解,您应该考虑提供赏金并将答案标记为正确。祝你今天过得愉快。 ;) 谢谢。我还是有一些麻烦。表格视图列出了self.user(但单元格的数量正确)。我已对我的原始问题进行了修改。 对不起,我无法理解您的评论。您能否在问题中提供更多详细信息? 具体来说,tableview 列出 self.user 是什么意思?【参考方案2】:

您应该在对象之间建立关系。您不必将userID 存储在Follower 对象中。这样你就可以简单地写:

predicate = [NSPredicate predicateWithFormat:@"user = %@", self.user];

这将返回与self.user 有关系的所有Followers。希望这会有所帮助。

【讨论】:

所以你的意思是用户模型应该和它自己有关系(在你的例子中叫做用户)? @Anders 是的,这称为反向关系,您应该始终拥有反向关系。 Core Data 使用它们来维护图的完整性。 +1 为您的回复。很好。我之前的评论集中在 IN 子句的语法上,但你明白了。 你的User 类型对象应该有一个followers 类型为NSSet 的属性,你的Follower 对象应该有一个user 类型为User 的属性。如果你有这个,你用实体Follower创建一个NSFetchRequest。谓词中的表达式基本上意味着,您希望每个现有的 follower 具有它的 user 属性等于 self.user 没有让它工作。您的示例不返回 1 个等于 self.user 的用户吗?在我的关注者表中是 0。

以上是关于具有多对多关系的 NSPredicate的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4:具有额外关系的多对多

PostGraphile deleteEdge 具有多对多关系

具有多对多关系的类型元素的 GraphQL 解析器

预加载具有多对多关系的核心数据的最佳实践

删除具有多对多关系的行

核心数据。加入 2 个具有多对多关系的表?