作为一个简单的例子,假设我有2个具有多对多关系的实体。第一个实体被称为" Projects"和第二个"员工"。项目实体可以有一个或多个员工,员工可以在一个或多个项目上。
为简单起见,Project有一个名为projectName的属性,以及与Employee一起调用withEmployees的多对多关系。相反,Employee具有employeeName和与myProjects项目的多对多关系。
使用NSFetchedResultsController我想要一个将projectName作为行名称和employeeName的表。使用Project作为获取的实体,我可以轻松获取每个项目并创建相应的部分名称。但是,在计算numberOfRowsInSection时会出现问题。当获取的结果撤回项目的一条记录时,numberofrows只看到一个实体,因为它没有查看.withEmployees关系中找到的NSSet。这意味着只输出一个员工而不是NSSet关系中的数字计数。
如何在表格中使用多对多关系来最好地克服这个问题?
感谢。
以下是fetchedcontroller的代码:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Projects"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *firstSort = [[NSSortDescriptor alloc] initWithKey:@"projectName"
ascending:NO];
NSArray *sortDescriptors = @[firstSort];
[fetchRequest setSortDescriptors:sortDescriptors];
_fetchedController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:@"projectName"
cacheName:nil];
答案 0 :(得分:1)
我终于找到了答案。我所拥有的实体关系如上所述都很好。问题再次是获得通过to to many关系返回的正确行数。我用以下方式解决了这个问题:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
Projects *project = [self.fetchedController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]];
return [project.withEmployees count];
}
通过上面我使用了相应的部分,因为我知道总有一行包含一组未知大小,我创建了一个索引路径,它查找每个部分的唯一一个头记录(项目) 。然后我只是查看构成关系的NSSet并简单地返回它的计数。现在我们得到每个部分正确的行数。
至于细胞本身:
Projects *project = [self.fetchedController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:atIndex.section]];
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:atIndex];
NSArray *empArray = [project.withEmployees allObjects];
Employee *employee = [empArray objectAtIndex:atIndex.row];
cell.textLabel.text = employee.firstName;
}
这里的关键是获取一节记录,然后提取构成多对多关系的所有数据。我再次需要创建一个索引路径,以便只获取父记录。现在使用行我可以遍历数组来获取每个元素。
答案 1 :(得分:0)
像
这样的东西- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id<NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
这假设您已在提取的结果控制器的sectionNameKeyPath:
电话中传递了正确的-initWithFetchRequest:managedObjectContext:sectionNameKeypath:cacheName:
。
附注:关系名称通常遵循与属性或属性相同的命名规则。使用myProjects
和withEmployees
代替projects
和employees
。它会让您的代码更好:fred.projects
代替fred.myProjects
,lawnmower.employees
代替lawnmower.myEmployees
。
答案 2 :(得分:0)
我还不能发表评论,所以请将此作为答案并可能添加到上面的代码中:
我设法在NSSet中检索关系的实体并在tableview中显示它。
但是我现在正试图对该tableview实现slide-to-delete,而我的NSFRC无法注册关系数组中对象的删除。
在这个例子中,这意味着:我可以删除一个Project对象,但是如果我删除了一个Employee对象,它会崩溃,因为它会注册(0,0)添加/删除的行。
我以相同的方式获取它,然后删除该对象:
NSArray *empArray = [project.withEmployees allObjects];
Employee *employee = [empArray objectAtIndex:atIndex.row];
[context deleteObject:employee];
你有任何机会可以解决这个问题吗?
我目前在我的NSFRC中没有谓词,如果它检查了project.employee的东西会改变什么?或者我应该使用2个NSFRC,一个加载Projects并设置部分,一个加载Employees并加载行?我认为他们在检测到已删除的对象时可能仍然会干扰。