核心数据从具有多对多关系的集合中检索数据

时间:2013-07-09 20:27:58

标签: core-data many-to-many nsfetchrequest nsset

我是核心数据的新手,我仍然试图理解它。我有一个问题,我花了几个小时试图解决。我似乎无法解决它,并希望有人可以帮助我。

我无法发布图片,所以这里是我的数据模型的链接:

http://yourpcsolution.net/model.png

每个关系都有反转。游戏可以有许多时段,而时段可以有很多玩家。玩家可以在一个以上的时间段内。

以下是填充DB的代码:

- (void) prepareDB {
Games *game = [NSEntityDescription insertNewObjectForEntityForName:@"Games" inManagedObjectContext:self.managedObjectContext];
game.date = [NSDate date];
game.name = @"Game 1";

Periods *period = [NSEntityDescription insertNewObjectForEntityForName:@"Periods" inManagedObjectContext:self.managedObjectContext];

period.date = [NSDate date];
period.name = @"1st Period";

NSMutableSet *gameSet = [[NSMutableSet alloc] initWithObjects:period, nil];

game.periods = gameSet;

Players *player = [NSEntityDescription insertNewObjectForEntityForName:@"Players" inManagedObjectContext:self.managedObjectContext];

player.name = @"Player1";

NSMutableSet *playerSet = [[NSMutableSet alloc] initWithObjects:player, nil];

period.players = playerSet;

NSError *error;
if (![self.managedObjectContext save:&error]) {
    NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
}

我认为这是添加数据的正确方法,因为在查看sql db时数据就在那里。我的问题是尝试检索属于每个时期的玩家。因为Periods是Games中的一个集合,所以玩家在核心数据的Periods中设置。所以我不能通过以下方式检索玩家:game.periods.players

这是我检索句点的代码,在xcode日志中我遇到了错误:

"Relationship 'players' fault on managed object (0x8e72bc0) <Periods: 0x8e72bc0>
(entity: Periods; id: 0x8e727c0 <x-coredata://7F63902B-FCB6-4ACA-BB40-904755D37A4A/Periods/p1>;
data: {\n    date = \"2013-07-09 19:35:48 +0000\";\n
games = \"0x8e6d760 <x-coredata://7F63902B-FCB6-4ACA-BB40-904755D37A4A/Games/p1>\";\n
name = \"1st Period\";\n    players = \"<relationship fault: 0x9840330 'players'>\";\n})"

我的检索期间代码:

NSString *firstPeriod = @"1st Period";
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", firstPeriod];
[request setEntity:[NSEntityDescription entityForName:@"Periods" inManagedObjectContext:self.managedObjectContext]];
[request setPredicate:predicate];

NSArray *period = [self.managedObjectContext executeFetchRequest:request error:&error];

我不知道如何从这里继续检索球员。我知道如何检索每个游戏属于哪个时段,但我不知道如何检索属于某个时段的玩家。我一直在努力解决这个问题,而这只是不起作用。

我的数据模型是否正确?我该如何检索数据?任何帮助或建议表示赞赏。

1 个答案:

答案 0 :(得分:1)

要获取给定时期内的所有玩家,以下内容应该有效:

NSString *firstPeriod = @"1st Period";

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Players" inManagedObjectContext:self.managedObjectContext]];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY periodsin.name == %@", firstPeriod];
[request setPredicate:predicate];

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

谓词中的“ANY”是必要的,因为每个玩家都连接到多个句号。

备注:多对多关系的数据类型为NSSet,而不是NSMutableSet

已添加:要获取给定播放器的所有期间,您可以使用以下提取请求:

Players *givenPlayer = ... ; // the given player
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Periods" inManagedObjectContext:self.managedObjectContext]];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY players == %@", givenPlayer];
[request setPredicate:predicate];
NSArray *periods = [self.managedObjectContext executeFetchRequest:request error:&error];

或者,您可以直接访问该关系:

Players *givenPlayer = ... ; // the given player
NSArray *periods = [givenPlayer.periodsin allObjects]; // "allObjects" converts NSSet to NSArray