NSFetchRequest用于双向多对多关系

时间:2013-06-03 21:03:10

标签: ios objective-c core-data nsfetchrequest

我最近开始使用CoreData并遇到了一个我无法弄清楚的复杂(至少对我来说)提取。我四处搜索,但很难找到一个好的术语来搜索,因此没有足够的结果。以下是我的coredata模型的基本示例:

enter image description here

我要做的是执行抓取以获取所有属于特定俱乐部的人员。示例:从国际象棋俱乐部获取所有成员。我可以用SQL轻松完成这个(有一个表示PersonInClub的第三个表,做两个表来组合两个表,选择所有人员,其中Club.name ='国际象棋俱乐部')但是我很难用fetch来实现这个请求。

我的最终目标是为NSFetchRequst写一个NSFetchedRequestController。这就是为什么我不能只为名称为Chess Club的俱乐部进行取得,然后抓住所有成员(除非我误解了某些内容,你能做到这一点并将结果放在控制器中吗?)。

非常感谢任何见解!

编辑:这是我的NSFetchedResultController的当前代码。不知道这会有什么帮助:

- (NSFetchedResultsController *)fetchedResultsController
{
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    [fetchRequest setEntity:[NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.managedObjectContext]];


    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];    
    [fetchRequest setSortDescriptors:@[sortDescriptor]];

    // This will give me the chess club but I want it's members!
    // I tried things like @"[self.name = %@ members]" and stuff to try and retrieve the members as the results
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self.name = %@", @"Chess Club"];
    [fetchRequest setPredicate:predicate];

    // an array with just the Chess Club in it
    NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];

    // Printing the members, The members are correct but again, they are not attached to the Controller, the actual club is
    NSSet *members = [results.lastObject members];
    NSMutableArray *memberNames = [NSMutableArray arrayWithCapacity:members.count];
    for (Person *p in [members allObjects])
        [memberNames addObject:p.firstName];
    NSLog(@"All Members: %@", memberNames); // prints all of the members accurantely

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return _fetchedResultsController;
}  

2 个答案:

答案 0 :(得分:4)

很久很久以后我终于明白了。它实际上很简单,我用于下面的代码(我已经包含了额外的代码来帮助澄清问题和答案):

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:NO];    
[fetchRequest setSortDescriptors:@[sortDescriptor]];

// This is the important part
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY self.clubs.name = %@", @"Chess Club"];
//

[fetchRequest setPredicate:predicate];

// Just to clarify received data
NSArray *allStudentsInChessClub = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];


NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
aFetchedResultsController.delegate = self;

// My NSFetchedResultsController with students from the Chess Club
self.fetchedResultsController = aFetchedResultsController;

我认为这不起作用,因为我认为它会尝试从name访问属性NSSet而不是集合中的值。这归功于国际象棋俱乐部的所有成员,而不是国际象棋俱乐部本身!

答案 1 :(得分:0)

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Club" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];    
[fetchRequest setSortDescriptors:@[sortDescriptor]];

// This is the important part
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", @"Chess Club"];
//

[fetchRequest setPredicate:predicate];

// Just to clarify received data
Club *club = [[self.managedObjectContext executeFetchRequest:fetchRequest error:nil] lastObject];

//所有俱乐部会员都可以通过club.member财产访问。如果你搜索一个俱乐部,我认为你不需要NSFetchedResultsController。

P.S。我建议你使用MagicalRecord框架。 (https://github.com/magicalpanda/MagicalRecord) 在这种情况下,您的代码将减少为1行代码:

Club *club = [Club MR_findFirstByAttribute:@"name" withValue:@"Chess Club"];
NSLog(@"club members %@", club.members);