我有一个对象NetworkMember没有属性,但由它的关系Person,Network,Level和Role定义。在我的应用程序中,我发现了所有四种关系,但是我想确保不要对NetworkMember进行双重注册,因此我想在实例化之前搜索此NSManagedObject。核心数据:通过其属性获取NSManagedObject
我应该如何编写一个查询来查询只包含关系的NSManagedObject?
干杯
聂
我有一个对象NetworkMember没有属性,但由它的关系Person,Network,Level和Role定义。在我的应用程序中,我发现了所有四种关系,但是我想确保不要对NetworkMember进行双重注册,因此我想在实例化之前搜索此NSManagedObject。核心数据:通过其属性获取NSManagedObject
我应该如何编写一个查询来查询只包含关系的NSManagedObject?
干杯
聂
您可以像针对属性一样针对关系编写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之间直接创建多对多关系,而无需自行维护任何中间实体或表。就像你在处理核心数据中的关系时不必担心主键和外键一样,该框架为你处理这种事情,让你在对象级别工作。
您可以使用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:
,看看有多少对象将被退回,如果你执行读取请求。如果你正在做这个测试很多,这可以更有效率。
所以它不可能通过核心数据,否则将使用在sqlite3的分贝幕后的ID查询? – niklassaers 2010-05-13 18:49:18
您的数据不一定存储在sqlite数据库中。核心数据还支持XML和二进制格式,因此将核心数据视为数据库并不准确。核心数据确实有'NSManagedObjectID'类唯一标识每个对象,并有你可以用它来获取基于这些ID对象的方法。 – Alex 2010-05-13 20:44:20
您不应该依赖'-objectID'属性,因为它可以并且确实会更改。你唯一应该使用它的时候是在线程之间传递引用。除此之外不要依赖它。如果你需要一个独特的创建你自己的。 – 2010-05-15 16:08:29
非常感谢你,这是我希望的方式,它可以这样做。 :-) – niklassaers 2010-05-24 08:32:22
只是一个很小的修正:取应该在某些时候,无论是在返回之前初始化或发送释放后调用自动释放被释放。顺便说一句,克里斯,你的博客文章已与其他核心数据问题,所以谢谢你一个巨大的帮助! – 2012-01-10 21:38:01