如何在 Core Data 中设置一对多关系的排序?

Posted

技术标签:

【中文标题】如何在 Core Data 中设置一对多关系的排序?【英文标题】:How to set ordering for one-to-many relationship in Core Data? 【发布时间】:2011-07-11 23:56:50 【问题描述】:

假设我有一个包含许多 Player 对象的 Game 对象(棒球比赛)。每场比赛的阵容都有特定的排序。

对于这种情况下如何存储订单有什么建议吗?

如果只有一个游戏,我可以简单地在每个 Player 对象中存储一个索引。但是,这个顺序会因每场比赛而改变。因此,如果 Player 对象被删除,我想确保 Game 对象也得到更新(保持引用完整性)。

对于我正在做的事情,我总是有 2 到 4 个玩家。

我尝试在 Game 对象中为每个玩家创建单独的关系,例如“playerOne”、“playerTwo”等。但是,当我尝试在 Player 对象中创建反向关系时,我只能设置“游戏”与其中一位玩家的关系(“playerOne”、“playerTwo”等)。

接下来我可能会尝试在 Player 对象中创建四个反向关系,以专门指向 Game 对象中的关系,但我认为这不正确并且会非常混乱。

另一种选择是,我可以将每个玩家对象的完整 URL 作为字符串存储在游戏对象中。但是,我需要管理删除等等。

感谢任何建议。

【问题讨论】:

【参考方案1】:

我过去也遇到过类似的问题。我个人的做法是对它们进行索引。添加一些属性,例如index。然后,每当进行更改时,调用一些重新标记索引的本地方法。这是一个粗略的例子,应该给出基本逻辑

- (void)retagPlayers 
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Players" inManagedObjectContext:self.managedObjectContext];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"game like %@", currentGame];
    NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES];
    [request setEntity:entity];
    [request setSortDescriptors:[NSArray arrayWithObject:sorter]];
    [request setPredicate:predicate];

    NSError *error = nil;
    NSArray *players = [self.managedObjectContext executeFetchRequest:request error:&error];

    int index = 0;
    for (Player *player in players) 
        player.index = index;
        index++;
    

这假设了一些事情,所以我应该指定其中一些。在其中,它假设您有一个名为 Players 的玩家实体。并且每个都与game 有关系,在这种情况下是一个字符串。这些东西在您的代码中可能会有所不同,并且可以相应地进行更改。无论哪种方式,逻辑都是相同的。它基本上在您的上下文中搜索特定游戏的 Player 实例(使用谓词),然后按索引对它们进行排序。然后它枚举返回的数组并将新索引设置为更改后的值。希望对你有帮助

【讨论】:

谢谢。我确实在我的帖子中提到过使用索引。但是,每个玩家的顺序与每个游戏相关,并且必须以某种方式存储。您的示例只是从零开始设置索引值,而不考虑索引应该是什么。我想我可能只存储对象 URL。 经过一番思考,我认为也许全局索引可以应用于所有 Player 对象 0..n。然后,每个 Game 对象可以存储四个索引,从而保持玩家的顺序。例如,playerOne = 8、playerTwo = 1、playerThree = 2、playerFour = 5。可以使用查找方法来检索对应于相应索引的 Player。由于我需要执行数据迁移,目前这可能很难做到。我会再考虑一下。 在我的示例中,我只是提供了一种更新值的方法,以使它们在初始设置之前保持有序。这将由您来初始化。我也会尝试为此举一个例子,但我不想强加太多,因为我不知道您的应用程序在这方面是如何设置的。只要您可以为您的玩家设置一些初始顺序,上述逻辑应该可以帮助您在添加/删除玩家时保持该顺序【参考方案2】:

如果我理解你的问题,你需要“游戏”和“玩家”之间的多对多关系,而不是一对多。此外,由于您需要对每个关系进行排序功能,您必须创建一个全新的实体来管理:

    “游戏”和“玩家”之间的多对多关系 每个“玩家”对一个“游戏”(和反向)的排序

我推荐一个名为“GamesPlayers”的实体,它具有两个对多的关系,一个与“Game”实体,一个与“Player”实体。最后,您需要添加一个排序属性 - 我不会将其称为“索引”,因为这是 Apple 在 Cocoa 框架中经常使用的一个非常常见的名称

要管理随着关系变化而更新的排序属性,您应该为“GamesPlayers”创建一个 NSManagedObject 子类,覆盖 addGamesObject:removeGamesObject: 以及 addPlayersObject:removePlayersObject: 实体。

【讨论】:

谢谢弗洛里安。我想我可以得到这样的工作。然而,经过深思熟虑,我认为最好为每个玩家添加一个迭代的“索引”属性,从零开始。然后我可以将此索引值用于 playerOne、playerTwo 等。它将需要我管理玩家的添加/删除。我今天早上才想到这个解决方案。

以上是关于如何在 Core Data 中设置一对多关系的排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 上的 Core Data 中设置新创建的关系?

Core Data中设置实体间关系的原因

如何管理 Core Data 中的一对多关系?

如何管理 Core Data 中的一对多关系?

需要在 Laravel 4 的同一张表中设置一对多关系

如何在graphql突变中设置多对多关系?