1

问题是我不知道如何制作一个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 ...];
4

3 回答 3

8

它比你想象的要复杂,但也不是不可能。

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

如果您使用 Core Data 的预期用途——在这种情况下是两个实体之间的关系——查找会很简单。您可以为每个Library在其books关系中没有条目的情况进行提取。

话虽如此,您分两步解决眼前的问题。

首先,获取lib_idBooks. 以下将为您提供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;
}
于 2013-01-04T18:29:44.450 回答
0

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

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

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

于 2013-01-04T10:47:10.287 回答
0

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

但是您可以拥有 N 个相关实体 => 让一个实体相互继承

所以..您可以让 A1 扩展 A 和 A2 扩展 A:
=> A1 和 A2 存储在一个表中,并且可以在一次提取中查询它们(获取所有 As)

但是..您无法获取无关的 A 和 B:
=> 一次获取无法完成

于 2013-01-04T20:18:09.413 回答