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 に答える