核心数据:NSPredicate,可查看两个实体

时间:2013-01-04 09:37:56

标签: objective-c ios core-data nsfetchrequest

问题在于我不知道如何制作一个看起来在两个实体中的NSPredicate。有什么想法吗?

假设我有2个实体:

Library:
1 lib_id
2 name
3 address

Books
1 book_id
2 book_name
3 book_author
4 lib_id

它们之间没有任何核心数据关系。我想创建一个获取请求,该请求将返回包含至少一本书的所有库的NSArray。

我认为它是这样的:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescriptor *entity = [NSEntityDescriptor entityForName:@"Books" inManagedObjectContext:context];
 // some NSPredicate...
array = [context executeFetch ...];

3 个答案:

答案 0 :(得分:8)

它比你想象的要复杂,但并非不可能。

您的数据模型在两个实体上使用lib_id,以及您无法在实体之间添加核心数据关系的评论表明您陷入了经典陷阱:您是像关系数据库一样处理核心数据。 Core Data的API不像关系数据库那样设计。您可以通过这种方式使其工作,但是您应该意识到您将竭尽全力使核心数据变得更加困难。如果下面的解决方案看起来很复杂,那是因为你的核心数据错误

如果您正在使用Core Data,因为它打算使用 - 在这种情况下,两个实体之间存在关系 - 查找将很简单。您可以为每个Library执行抓取,但books关系中没有条目。

话说回来,你分两步解决了眼前的问题。

首先,获取lib_id实例上使用的Books的每个唯一值。以下内容将为您提供包含与唯一值匹配的字符串NSArray

NSFetchRequest *bookRequest = [NSFetchRequest fetchRequestWithEntityName:@"Books"];
[bookRequest setPropertiesToFetch:@[@"lib_id"]];
[bookRequest setResultType:NSDictionaryResultType];
[bookRequest setReturnsDistinctResults:YES];

NSError *error = nil;
NSArray *libIdsInBooksDicts = [[self managedObjectContext] executeFetchRequest:bookRequest error:&error];
if (libIdsInBooksDicts == nil) {
    NSLog(@"Fetch error: %@", error);
    return;
}

NSArray *libIdsInBooks = [libIdsInBooksDicts valueForKey:@"lib_id"];

上面的最后一行是因为libIdsInBooksDicts实际上包含一个字典数组,而每个字典又有一个名为lib_id的键和一个实际ID的值。你只想要价值观。

接下来,查看Library位于您刚刚获得的列表中的每个lib_id

NSFetchRequest *libRequest = [NSFetchRequest fetchRequestWithEntityName:@"Library"];
[libRequest setPredicate:[NSPredicate predicateWithFormat:@"lib_id in %@", libIdsInBooks]];

error = nil;
NSArray *librariesWithAtLeastOneBook = [[self managedObjectContext] executeFetchRequest:libRequest error:&error];
if (librariesWithAtLeastOneBook == nil) {
    NSLog(@"Fetch error: %@", error);
    return;
}

答案 1 :(得分:0)

NSFetchedResultsController可以使用sectionNameKeyPath帮助获取结果。

- (id)initWithFetchRequest:(NSFetchRequest *)fetchRequest 
      managedObjectContext:(NSManagedObjectContext *)context 
        sectionNameKeyPath:(NSString *)sectionNameKeyPath 
                 cacheName:(NSString *)name;

如果将lib_id作为sectionNameKeyPath传递,您将获得多个部分的数据,每个部分关联不同的lib_id。

答案 2 :(得分:0)

一次获取==一个DISTINCT实体。

但你可以有N个相关的实体=>让一个人继承彼此

所以..你可以有A1延伸A和A2延伸A:
    => A1& A2存储在一个表中,可以在一次获取(全部获取)

中查询它们

但是......你无法获取不相关的A和B:
    =>一次获取无法做到