0

我有一个使用两个独立核心数据存储的应用程序。一种用于用户数据,一种用于只读内容数据。为了在它们之间创建关系,当然禁止使用关系,因此对内容存储的引用由 id 管理。

这在大多数情况下都可以正常工作,但对于某些特定的提取,它被证明是困难的。

以下面的例子为例:假设我有一个应用程序,它有几百部电影(每部电影都有一条记录存储在只读存储中),并且每当用户观看一部电影时,都会在可写用户存储中创建一条记录。我可能会将我的模型设置为有一个名为 Movie 的实体,以及另一个名为 MovieHistory 的实体。

电影有:一个称为标识符(NSNumber)的属性。

MovieHistory 具有:一个名为movieIdentifier 的属性(对Movie 的跨存储引用)、一个viewDate 属性(NSDate)和一个获取的属性“movie”,其目的地设置为Movie,谓词为(SELF.identifier == $FETCH_SOURCE.电影标识符)。

假设我现在想要观看最后 10 部电影,没有重复(如果我观看了我以前看过的电影,它应该跳到列表的顶部)。我希望能够使用以下代码:

NSError *error = nil;

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName: @"MovieHistory"];

NSSortDescriptor *dateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"viewDate" ascending:NO];

NSEntityDescription* entity = [NSEntityDescription entityForName:@"MovieHistory" inManagedObjectContext: moc];
NSAttributeDescription* movieIdentifierDesc = [entity.attributesByName objectForKey:@"movieIdentifier"];
NSFetchedPropertyDescription *movieDesc = [entity.propertiesByName objectForKey:@"movie"];

[request setFetchLimit: limit];
[request setSortDescriptors: [NSArray arrayWithObject: dateDescriptor]];
[request setPropertiesToFetch:[NSArray arrayWithObjects: movieIdentifierDesc, movieDesc, nil]];
[request setPropertiesToGroupBy:[NSArray arrayWithObject: movieIdentifierDesc]];
[request setResultType:NSDictionaryResultType];

NSArray *results = [moc executeFetchRequest: request error: &error];

if(error != nil)
    NSLog(@"Error fetching last viewed movies: %@", error);

return results;

此代码引发异常,指出获取的属性(“MovieHistory”中的“movie”)是在这种情况下使用的无效属性。使用 NSDictionaryResultType 时不能使用获取的属性。但是,如果返回类型不是 NSDictionaryResultType,您也不能使用 setPropertiesToGroupBy:。我需要分组以便按日期排序并删除重复的电影。

当我从发送到 setPropertiesToFetch: 的数组中删除获取的属性时,它工作正常。但是当然我必须在一个循环中一个接一个地取出每个 MovieRecord。

完成我想做的事情的最佳方法是什么?有没有办法做到这一点,而不必求助于获取 ID,然后逐个循环遍历结果?

谢谢,

4

1 回答 1

0

我没有完全按照你的整个帖子,但是......

您可以发出两个单独的提取操作。第一个从该数据库中获取 MovieHistory 对象。

将所有电影标识符放入一个集合中,然后使用 IN 关键字从电影数据库中获取。

NSPredicate *moviePredicate = [NSPredicate predicateWithFormat: @"identifier IN %@", allMovieIdentifiers];

它不像其他一些解决方案那样优雅,但它易于编写,更重要的是,易于阅读、理解和更改。记住首先为程序员优化。

于 2012-07-12T17:44:15.310 回答