Core data 核心数据-从多个关系构建NSPredicate

Core data 核心数据-从多个关系构建NSPredicate,core-data,many-to-many,nsfetchedresultscontroller,nspredicate,nsfetchrequest,Core Data,Many To Many,Nsfetchedresultscontroller,Nspredicate,Nsfetchrequest,这是我上一个问题的后续问题: 有一个关于这个问题的图表,下面是一个快速提醒: 公司----员工 我已经能够在每个实体中手动保存1个实体,并在NSLog中验证它们 我已经创建了一个列出所有公司的CompanyListPage。这个想法是,当你点击一家公司时,你会看到一个与该公司有合同的所有员工的列表 如下所示: 公司: 姓名:A 合同: 长度:33周 工资:20000 雇员: 姓名:鲍勃·琼斯 在我公司页面内的DidSelectRowatinex页面中,我有以下内容 -(void)tableV

这是我上一个问题的后续问题:

有一个关于这个问题的图表,下面是一个快速提醒:

公司----员工

我已经能够在每个实体中手动保存1个实体,并在NSLog中验证它们

我已经创建了一个列出所有公司的CompanyListPage。这个想法是,当你点击一家公司时,你会看到一个与该公司有合同的所有员工的列表

如下所示:

公司:
姓名:A
合同:
长度:33周
工资:20000
雇员:
姓名:鲍勃·琼斯
在我公司页面内的DidSelectRowatinex页面中,我有以下内容

-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(nsindepath*)indepath{
公司*c=[fetchedResultsController对象索引路径:indexPath];
NSLog(@“您点击了%@”,c.name);
NSString*companyName=c.name;
EmployeesListPage*EmployeesListPage=[[EmployeesListPage alloc]initWithNibName:@“EmployeesListPage”捆绑包:[NSBundle mainBundle]];
[self.navigationController pushViewController:employeesListPage动画:是];
employeesListPage.title=公司名称;
employeesListPage.managedObjectContext=self.context;
employeesListPage.managedObject=c;
[超级明星名单发布];
}
然而,问题是,我不确定当我最终去员工公寓时,我的NSPredicate应该是什么样子

目前的情况是:

-(NSFetchedResultsController*)fetchedResultsController
{
if(fetchedResultsController!=nil){
返回获取的ResultsController;
}
//创建并配置提取请求
NSFetchRequest*fetchRequest=[[NSFetchRequest alloc]init];
NSEntityDescription*entity=[NSEntityDescription entityForName:@“Employees”在managedObjectContext:managedObjectContext中];
[FetchRequestSetEntity:entity];
//创建排序描述符数组
NSSortDescriptor*authorDescriptor=[[NSSortDescriptor alloc]initWithKey:@“name”升序:YES];
NSArray*sortDescriptors=[[NSArray alloc]initWithObjects:authorDescriptor,nil];
[FetchRequestSetSortDescriptors:sortDescriptors];
//创建并初始化“获取结果”控制器
NSFetchedResultsController*aFetchedResultsController=[[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@“Root”];
self.fetchedResultsController=aFetchedResultsController;
fetchedResultsController.delegate=self;
//内存管理。
[aFetchedResultsController释放];
[请求释放];
[作者描述者发布];
[sortDescriptors发布];
返回获取的ResultsController;
}    
显然这是错误的,因为它不是:

a) 查看合同实体 b) 以任何方式、形式或形式使用公司实体

我知道我需要使用NSPredicate,但我只知道如何让它说“找到所有合同长度>0且与a公司合作的员工”,然后按降序人员的姓名排序,甚至可以先按最小合同长度排序

任何关于这方面的建议或帮助都会很好。多谢各位


编辑:第一次尝试(已删除,因为我根据下面提供的答案使其工作)

编辑:无法取回合同信息

我已经能够让A公司的所有员工回到我的表视图控制器中

但是,我希望在我的手机中显示有关员工及其合同期限/工资的信息

我尝试了以下方法:

Employee*emp=[fetchedResultsController对象索引路径:indexPath];
NSString*firstname=emp.firstname;
NSString*姓氏=皇帝姓氏;
NSString*fullname=[firstname stringByAppendingString:@”“;
fullname=[fullname stringByAppendingString:姓氏];
//测井测试
NSLog(@“名称:%@”,全名);//这很好
NSLog(@“合同:%@”,emp.emp合同);//这告诉我一个关于“错误的关系”的问题
我相信我需要让NSPredicate获取所有合同数据,而不仅仅是合同数据;然而,我可能弄错了


再次感谢您在这方面的帮助。

我认为如果您使用ANY关键字,您将把等式的左侧恢复为单个数量,这将与等式的右侧一致:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@“ANY contracts.employer ==  %@“, employer];

我想我现在有答案了

我在我的表视图中执行了以下操作,得到了一个有效的关系和所有输出;然而,我不确定我是否做得对,因为它涉及一个for循环

我在解决方案中使用了以下与StackOverflow相关的方法

- (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循环不是实现这一点的最有效的方法,我将欢迎任何建议/改进,甚至是最佳实践


谢谢。

看起来进展顺利。我想您只需要设置单元格的文本:cell.textlab=fullname

但我不清楚你为什么要重新研究合同关系——直到我看到你顶部的示例文本。在这里,您需要的似乎是雇主的合同列表,对于每个合同,您需要显示其与一个员工的关系和其他属性。在这种情况下,您根本不需要重新获取;你已经有了雇主,通过它与多个合同的关系,你也有了合同实体,通过它们,还有期限、工资、雇员等等

在雇主表中更改选择后,您将执行以下操作:

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
}}