3

我有一个应用程序一直显示商店的销售量。

NSNumber *amount = [self valueForKeyPath:@"sales.@sum.value"];

现在我必须过滤并按期间显示金额。我有包含月份和年份的字段“句点”(字符串),例如“2012-11”。

如何使用 where 子句进行相同的查询?

4

1 回答 1

3

您可以在计算总和之前过滤销售额。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"period == %@", @"2012-11"];
NSSet *sales = [self valueForKeyPath:@"sales"];
NSSet *filteredSales = [sales filteredSetUsingPredicate:predicate];
NSNumber *amount = [filteredSales valueForKeyPath:@"@sum.value"];

但是当你有几十个或更多的销售时,这种方法并不是很有效,因为它需要将每个销售加载到内存中。

此外,如果销售出现故障,每个销售都会触发故障并生成 SQL 请求。您可以通过在过滤之前对销售进行批量故障来防止这种情况。

我们将假设它self是一个托管对象。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"period == %@", @"2012-11"];
NSSet *sales = [self valueForKeyPath:@"sales"];
// Begin batch-faulting
NSManagedObjectContext *moc = [self managedObjectContext];
NSFetchRequest *request = [NSFetchRequest new];
[request setEntity:[NSEntityDescription entityForName:@"Sale" inManagedObjectContext:moc]];
[request setPredicate:[NSPredicate predicateWithFormat:@"self IN %@", sales]];
[request setReturnsObjectsAsFaults:NO];
[moc executeFetchRequest:request error:NULL];
// Batch-faulting done
NSSet *filteredSales = [sales filteredSetUsingPredicate:predicate];
NSNumber *amount = [filteredSales valueForKeyPath:@"@sum.value"];

但是,您仍然会为每次销售获得多个分配(托管对象、它的缓存、它的属性)。最好的解决方案是使用获取请求来计算 SQLite 数据库中的总和。

NSString *reverseRelationship = @"store"; // name of the relationship from the sale to self
NSExpressionDescription *description = [NSExpressionDescription new];
[description setName:@"amount"];
[description setExpressionResultType:NSDoubleAttributeType];
[description setExpression:[NSExpression expressionWithFormat:@"@sum.value"]];
NSManagedObjectContext *moc = [self managedObjectContext];
NSFetchRequest *request = [NSFetchRequest new];
[request setEntity:[NSEntityDescription entityForName:@"Sale" inManagedObjectContext:moc]];
[request setResultType:NSDictionaryResultType];
[request setPredicate:[NSPredicate predicateWithFormat:
                       @"%K == %@ AND period == %@", reverseRelationship, self, @"2012-11"]];
[request setPropertiesToFetch:@[description]];
NSDictionary *result = [[moc executeFetchRequest:request error:NULL] lastObject];
NSNumber *amount = [result objectForKey:@"amount"];
于 2013-01-14T18:44:29.393 回答