这是我之前提出的问题的后续问题:
Core data: Managing employee contracts in a many-to-many relationship?
该问题有一个图表,作为快速提醒,有以下内容:
company --< contracts >-- employees
我已经能够在每个实体中手动保存1个实体,并在NSLog中验证它们。
我创建了一个列出所有公司的CompanyListPage。我们的想法是,当您点击公司时,您将看到与该公司签订合同的所有员工的列表。
如上下文所示:
Company:
name: A
Contract:
length: 33 wks
salary: 20000
Employee:
name: Bob Jones
在我的CompanyListPage中的didSelectRowAtIndex页面中,我有以下内容。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Company *c = [fetchedResultsController objectAtIndexPath:indexPath];
NSLog(@"You clicked %@", c.name);
NSString *companyName = c.name;
EmployeesListPage *employeesListPage = [[EmployeesListPage alloc] initWithNibName:@"EmployeesListPage" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:employeesListPage animated:YES];
employeesListPage.title = companyName;
employeesListPage.managedObjectContext = self.context;
employeesListPage.managedObject = c;
[superstarsList release];
}
然而问题是,当我最终访问employeesListPage时,我不确定我的NSPredicate应该是什么样子。
目前,它是这样的:
- (NSFetchedResultsController *)fetchedResultsController
{
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
// Create and configure a fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Employees" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// Create the sort descriptors array
NSSortDescriptor *authorDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:authorDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Create and initialize the fetch results controller
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
self.fetchedResultsController = aFetchedResultsController;
fetchedResultsController.delegate = self;
// Memory management.
[aFetchedResultsController release];
[fetchRequest release];
[authorDescriptor release];
[sortDescriptors release];
return fetchedResultsController;
}
显然这是错误的,因为它不是:
a)查看合同实体 b)以任何方式,形式或形式使用公司实体
我知道我需要使用NSPredicate,但我只知道如何让它说“找到我所有合同长度大于0且与公司A合作的员工”,然后按照降序人员的名义订购,或者甚至先按最小合同长度订购。
任何关于此的指示或帮助都会很棒。谢谢。
编辑:第一次尝试(删除,因为我按照下面提供的答案让它工作)
编辑:无法获得合同信息?我已经能够让所有为公司A工作的员工回到我的表视图控制器中。
但是我想在我的单元格中显示有关员工及其合同期限/工资的信息。
我尝试了以下内容:
Employee *emp = [fetchedResultsController objectAtIndexPath:indexPath];
NSString *firstname = emp.firstname;
NSString *surname = emp.surname;
NSString *fullname = [firstname stringByAppendingString:@" "];
fullname = [fullname stringByAppendingString:surname];
// Logging tests
NSLog(@"Name: %@", fullname); // This is fine
NSLog(@"Contracts: %@", emp.empContracts); // This tells me of a problem with "Relationship fault for <NSRelationshipDescription: 0x602fdd0>"
我认为我需要让NSPredicate获取所有合同数据,而不仅仅是合同数据;但是我可能弄错了。
再一次,对此的帮助将不胜感激。
答案 0 :(得分:1)
我认为如果您使用ANY关键字,您可以将等式的左侧恢复为单个数量,这将与等式的右侧一致:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@“ANY contracts.employer == %@“, employer];
答案 1 :(得分:0)
我想我现在有一个答案。
我在表视图中执行了以下操作,并获得了有效的关系和所有输出;但是我不确定我是否正确,因为它涉及一个for循环。
我使用了与我的解决方案相关的以下StackOverflow question/answer。
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
Employee *emp = [fetchedResultsController objectAtIndexPath:indexPath];
NSString *firstname = emp.firstname;
NSString *surname = emp.surname;
NSString *fullname = [firstname stringByAppendingString:@" "];
fullname = [fullname stringByAppendingString:surname];
NSLog(@"Employee: %@", fullname);
// Output the contract deals.
for (Contracts *deals in emp.contracts)
{
NSNumber *cLength = deals.length;
NSNumber *cSalary = deals.salary;
NSLog(@"Length: %@", cLength);
NSLog(@"Salary: %@", cSalary);
} // next
}
我的下一步是将其包含在自定义视图中,并使用自定义标签来保存所有这些信息。
如果for循环不是最有效的方法,我欢迎任何建议/改进,甚至是最佳实践。
谢谢。
答案 2 :(得分:0)
看起来它很顺利。我想你需要的就是设置单元格的文本:cell.textLabel = fullname。
但是我不清楚你为什么要深入研究合同关系 - 直到我在顶部看你的示例文本。在那里,您想要的是雇主的合同列表,以及您希望展示其与一个员工关系和其他attrs的每个合同。在这种情况下,您根本不需要新的提取;你已经拥有了雇主,并且通过其多对多的合同关系,你也拥有合同实体,通过它们,还有工资,工资,雇员等等。
在雇主表中选择更改后,您将执行以下操作:
NSUInteger row = [indexPath row];
Employer *employer = [self.arrayOfEmployersUsedToPopulateTable objectAtIndex:row];
self.selectedEmployer = employer;
self.arrayOfSelectedEmployersContracts = [employer.contracts allObjects]; // which probably faults them, but I think that’s OK here
// Then make a call to reload the other table, the one presenting the contracts info.
在合同表中,您将返回选定的雇主,并提供每份合同的信息:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
Contract *contract = [self.arrayOfSelectedEmployersContracts objectAtIndex:row];
NSUInteger column = [indexPath column];
switch (column) {
(0) :
cell.textLabel = contract.length; // maybe you have to use an NSNumber method to convert to string, but probably not
break;
(1):
cell.textLabel = contract.employee.firstname;
break;
// and so forth
}}
P.S。对于UITableCell的东西,我参考了Mark和LaMarche的“开始iPhone开发”,“使用新的表视图单元。”你可能也喜欢这本书。