获取复杂请求核心数据的谓词和表达式
Posted
技术标签:
【中文标题】获取复杂请求核心数据的谓词和表达式【英文标题】:Predicate and expression to fetch complex request core data 【发布时间】:2013-08-31 16:32:31 【问题描述】:我必须提出一个复杂的核心数据获取请求,但我不知道是否可以提出。 这是我的场景:只有一个具有这些属性的实体(费用):
成本 (NSDecimalNumber) 存款 (NSDecimalNumber) 类别(NSString) 付费(布尔值)请求应该返回 3 个最昂贵的类别,但这些是必须遵守的规则:
如果Paid == YES,应将费用成本添加到费用类别总计中 如果Paid == NO && Deposit > 0,费用押金应添加到费用类别总额中 如果Paid == NO,则不应将任何内容添加到费用类别总计中使用 NSExpression,我可以计算每个类别的每个总数,但它还包括未支付的费用成本。 有没有办法做到这一点? 非常感谢!
【问题讨论】:
【参考方案1】:例如,您可以使用NSFetchRequest
:
// Build the fetch request
NSString *entityName = NSStringFromClass([Expense class]);
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = entity;
仅过滤相关费用:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(paid == YES) OR ((paid == NO) AND (deposit > 0))"];
request.predicate = predicate;
并总结cost和depost属性:
NSExpressionDescription *(^makeExpressionDescription)(NSString *, NSString *) = ^(NSString *keyPath, NSString *name)
// Create an expression for the key path.
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:keyPath];
// Create an expression to represent the function you want to apply
NSExpression *totalExpression = [NSExpression expressionForFunction: @"sum:" arguments: @[keyPathExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
// The name is the key that will be used in the dictionary for the return value
expressionDescription.name = name;
expressionDescription.expression = totalExpression;
expressionDescription.expressionResultType = NSDecimalAttributeType;
return expressionDescription;
;
NSExpressionDescription *totalCostDescription = makeExpressionDescription(@"cost", @"totalCost");
NSExpressionDescription *totalDepositDescription = makeExpressionDescription(@"deposit", @"totalDeposit");
// Specify that the request should return dictionaries.
request.resultType = NSDictionaryResultType;
request.propertiesToFetch = @[categoryDescription,
paidDescription,
totalCostDescription,
totalDepositDescription];
并按类别和付费状态对结果进行分组:
// Get 'category' and 'paid' attribute descriptions
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName
inManagedObjectContext:context];
NSDictionary *attributes = [entity attributesByName];
NSAttributeDescription *categoryDescription = attributes[@"category"];
NSAttributeDescription *paidDescription = attributes[@"paid"];
// Group by 'category' and 'paid' attributes
request.propertiesToGroupBy = @[categoryDescription, paidDescription];
您将获得汇总的已付和未付费用
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
您需要做的就是合并(和排序)然后:
if (results)
NSMutableDictionary *combined = [NSMutableDictionary dictionary];
for (NSDictionary *result in results)
NSString *category = result[@"category"];
BOOL paid = [result[@"paid"] boolValue];
NSDecimalNumber *total = result[paid ? @"totalCost" : @"totalDeposit"];
NSDecimalNumber *sum = combined[category];
if (sum)
total = [total decimalNumberByAdding:sum];
combined[category] = total;
NSArray *sortedCategories = [combined keysSortedByValueUsingSelector:@selector(compare:)];
[sortedCategories enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop)
NSLog(@"Category %@: %@", obj, combined[obj]);
];
else
NSLog(@"Error: %@", error);
【讨论】:
eik,非常感谢!这正是我一直在寻找的东西,我挽救了我的一天! ;) 它就像一个魅力!以上是关于获取复杂请求核心数据的谓词和表达式的主要内容,如果未能解决你的问题,请参考以下文章
带有谓词的核心数据获取请求。需要正确的 NSPredicate