2010-05-13 131 views
1

我有一个对象NetworkMember没有属性,但由它的关系Person,Network,Level和Role定义。在我的应用程序中,我发现了所有四种关系,但是我想确保不要对NetworkMember进行双重注册,因此我想在实例化之前搜索此NSManagedObject。核心数据:通过其属性获取NSManagedObject

我应该如何编写一个查询来查询只包含关系的NSManagedObject?

干杯

回答

4

您可以像针对属性一样针对关系编写NSPredicate。

例如:

- (BOOL)isPerson:(Person *)person memberOfNetwork:(Network *)network { 
    // assume NetworkMember entity is ivar networkMemberEntity_ 
    // assume NSManagedObjectContext is ivar context_ 

    NSFetchRequest *fetch = [[NSFetchRequest alloc] init]; 
    [fetch setEntity:networkMemberEntity_]; 
    [fetch setPredicate:[NSPredicate predicateWithFormat: 
     @"(person == %@) AND (networks CONTAINS %@)", person, network]]; 
    [fetch setFetchLimit:1]; 

    NSError *error = nil; 
    NSInteger count = [context_ countForFetchRequest:fetch error:&error]; 
    if (count < 0) { 
     // always handle errors in real code 
     // and never check for errors using "error == nil" 
    } 

    return count > 0; 
} 

在你目前的情况,但是,你应该认真考虑是否真的需要做到这一点。这听起来像是你试图模拟Person和Network之间的多对多关系。如果你来自数据库背景,你可能会认为你需要一个连接表来完成这个工作,并创建一个中间实体。

但是,核心数据可以为您管理所有这些;您可以在Person和Network之间直接创建多对多关系,而无需自行维护任何中间实体或表。就像你在处理核心数据中的关系时不必担心主键和外键一样,该框架为你处理这种事情,让你在对象级别工作。

+0

非常感谢你,这是我希望的方式,它可以这样做。 :-) – niklassaers 2010-05-24 08:32:22

+0

只是一个很小的修正:取应该在某些时候,无论是在返回之前初始化或发送释放后调用自动释放被释放。顺便说一句,克里斯,你的博客文章已与其他核心数据问题,所以谢谢你一个巨大的帮助! – 2012-01-10 21:38:01

1

您可以使用NSPredicate与键值路径来指代关系作谓语,到NSFetchRequest。例如:

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
[request setEntity:[NSEntity entityForName:@"NetworkMember" inManagedObjectContext:managedObjectContext]; 
[request setPredicate:[NSPredicate predicateWithFormat:@"person.name == %@ AND ANY (roles.name == \"Manager\")", name]]; 
NSInteger count = [managedObjectContext countForFetchRequest:request error:&error]; 
[request release]; 
if (error) { /* handle the error */ } 
if (count != 0) { /* do something if the member already exists */ } 

如果你需要的是确认特定对象的存在,你可以使用的方法countForRetchRequest:error:,看看有多少对象将被退回,如果你执行读取请求。如果你正在做这个测试很多,这可以更有效率。

+0

所以它不可能通过核心数据,否则将使用在sqlite3的分贝幕后的ID查询? – niklassaers 2010-05-13 18:49:18

+0

您的数据不一定存储在sqlite数据库中。核心数据还支持XML和二进制格式,因此将核心数据视为数据库并不准确。核心数据确实有'NSManagedObjectID'类唯一标识每个对象,并有你可以用它来获取基于这些ID对象的方法。 – Alex 2010-05-13 20:44:20

+1

您不应该依赖'-objectID'属性,因为它可以并且确实会更改。你唯一应该使用它的时候是在线程之间传递引用。除此之外不要依赖它。如果你需要一个独特的创建你自己的。 – 2010-05-15 16:08:29