如何创建一个基于父关系过滤核心数据对象的 NSFetchRequest?

Posted

技术标签:

【中文标题】如何创建一个基于父关系过滤核心数据对象的 NSFetchRequest?【英文标题】:How to create an NSFetchRequest which filters Core Data objects based on parent relationships? 【发布时间】:2011-02-04 20:46:46 【问题描述】:

我有一个类似这样的核心数据模型:

公司实体 companyName 属性(字符串) 与 Employee 实体的多对多关系。 员工实体 employeeID 属性(字符串) 与母公司实体的一对一关系

我有一个根视图控制器,它在表格视图中列出了公司。然后选择一行将所选公司的索引推送到另一个视图控制器,该控制器在表中列出了员工。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)ip 

    EmployeeListViewController *anotherViewController = [[EmployeeListViewController alloc] init];
    [anotherViewController setCompany:[companyList objectAtIndex:[ip row]]];
    [[self navigationController] pushViewController:anotherViewController animated:YES];
    [anotherViewController release];

在 Employee 视图控制器中,公司被设置为 NSManagedObject。

- (void)setCompany:(NSManagedObject *)co

    [co retain];
    [company release];
    company = co;

    [self setTitle:[company valueForKey:@"companyName"]];

我添加新员工的代码如下所示:

employee = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:moc];
[[company mutableSetValueForKey:@"employee"] addObject:employee];
[employee setValue:employeeID forKey:@"employeeID"];

这看起来是正确插入数据库,我可以看到公司的外键 ID 插入到 Employee 表中。

我正在尝试获取公司中所有员工的信息,但我卡住了。

这是我对 NSFetchRequest 的要求,但它只给了我所有员工的信息(不是按公司):

NSManagedObjectContext *moc = [self managedObjectContext];

NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[fetch setEntity:[NSEntityDescription entityForName:@"Employee" inManagedObjectContext:moc]];
[fetch setEntity:entity];

NSError *error = nil;
NSArray *results = [moc executeFetchRequest:fetch error:&error];

[fetch release];

【问题讨论】:

【参考方案1】:

如果您为实体生成类,这可以很容易地处理。在 XCode 中编辑模型时,点击 Cmd-N 创建一个新文件。在左侧选择 ios Cocoa Touch Class,在右侧选择 Managed Object Class。 Hit Next、Next、Next 和代表您的实体的类文件将为您生成。

这些类非常有用,因为它们将帮助您管理对象之间的所有连接。在您的模型中,如果您定义从公司到员工的一对多关系并将其称为员工,那么您的公司类将有一个员工属性,它是与该特定公司关联的所有员工的 NSSet。这是梦幻般的。

您的创建代码看起来更像这样:

Employee *employee = (Employee*)[NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:moc];
employee.employeeID = employeeID;
[company addEmployeesObject:employee];

那么要获取与你公司相关的员工名单,就这么简单:

for(Employee *employee in company.employees) 
    // Do something with the employee

【讨论】:

谢谢肯尼。当我看到你回答时,我才开始阅读。我将把它标记为已回答,因为它让我走上了正确的轨道。

以上是关于如何创建一个基于父关系过滤核心数据对象的 NSFetchRequest?的主要内容,如果未能解决你的问题,请参考以下文章

从核心数据获取请求中排除反向关系

使用子属性过滤所有父对象

如何创建父实体和关系的核心数据模型

在不获取现有对象的情况下创建核心数据关系

父对象的核心数据列表关系

使用基于属性的过滤子元素集获取核心数据实体