the*_*ror 5 core-data nspredicate ios having-clause
对于我的生活,我似乎无法让这个工作.
假设我们的实体是一个具有状态字段和订单字段的托管对象.
我如何获得所有有序多个订单相同的订单?
请不要回答告诉我在主谓词中用@count做一个子查询,因为我知道这个解决方案,这篇文章的重点是要理解如何在核心数据中使用having谓词,这可能比一个更快无论如何都是子查询.(除非你解释为什么我不能使用having子句)
以下代码将返回一个字典数组,其中包含每个订单号的订单数.我想要的是能够添加一个having子句来限制我的请求只返回表示那些计数大于1的订单的对象的字典.
这是到目前为止的代码和我对谓词的尝试:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"OrderedEntry"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
[fetchRequest setResultType:NSDictionaryResultType];
NSPredicate *predicate = [NSPredicate predicateWithFormat:
@"(status == %@)",[NSNumber numberWithInt:EntryStatusAlive]];
[fetchRequest setPredicate:predicate];
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"order"]; // Does not really matter
NSExpression *maxExpression = [NSExpression expressionForFunction: @"count:"
arguments: [NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName: @"orderCount"];
[expressionDescription setExpression: maxExpression];
[expressionDescription setExpressionResultType: NSInteger32AttributeType];
[fetchRequest setPropertiesToFetch: [NSArray arrayWithObjects:expressionDescription,@"order",nil]];
[fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObjects:@"order",nil]];
//[fetchRequest setHavingPredicate:[NSPredicate predicateWithFormat:@"@count > 1"]];
//[fetchRequest setHavingPredicate:[NSComparisonPredicate predicateWithLeftExpression:maxExpression rightExpression:[NSExpression expressionForConstantValue:[NSNumber numberWithInteger:1]] modifier:NSDirectPredicateModifier type:NSGreaterThanPredicateOperatorType options:NSCaseInsensitivePredicateOption]];
NSError *error;
NSArray * array = [context executeFetchRequest:fetchRequest error:&error];
Run Code Online (Sandbox Code Playgroud)
首先,每当我尝试类似于您正在做的事情时,我都会收到一条错误,指出您无法将一对多关系传递给setPropertiesToFetch:. NSFetchRequest文档支持这一点:“属性描述可能表示属性、一对一关系或表达式。 ”所以这是问题 #1。
问题#2 是,您似乎也无法按一对多关系进行分组(文档中没有明确说明这一点,但您会得到相同的错误,而且这也是有道理的)。
从要获取的属性中删除“顺序”。按属性分组。修改您的主要谓词以仅包含您分组所依据的那些属性(或只是将其删除)。在having 谓词中指定“order”。
[fetchRequest setPropertiesToGroupBy: @[ @"???" ]];
[fetchRequest setHavingPredicate: [NSPredicate predicateWithFormat: @"self.order.@count > 1"]];
Run Code Online (Sandbox Code Playgroud)
现在您将看到该请求将起作用,但结果可能不是您所期望的:
- NSArray
- NSDictionary { status = @"alive", orderCount = "4" }
- NSDictionary { status = @"alive", orderCount = "9" }
- NSDictionary { status = @"alive", orderCount = "2" }
- etc...
Run Code Online (Sandbox Code Playgroud)
NSDictionaryResultType实际上并没有给你任何东西来识别这些对象 - 它只是给你值。
因此,下一步是取回这些OrderedEntry对象的 ID。诀窍是包含一个表达式,它将返回 NSManagedObjectID 作为每个字典中的键。
我不知道这是否真的会提高性能(不仅仅是将其与主谓词进行“与”运算)。根据我的经验,提高获取性能可以做的最好的事情之一就是创建单例 NSPredicates 并使用替换变量来设置每个获取。谓词解析可能会很昂贵。
字典结果类型可能很痛苦。通常,构建一个好的谓词会更好。我倾向于仅将它们用于表达式(即在返回值的图表上执行统计类型计算)。如果您查看有关要获取和分组的属性以及谓词限制的所有限制,您会发现这似乎就是 Apple 的目的。我什至不确定是否可以通过分组和使用having谓词来完成您想做的事情 - 例如,您要根据什么进行分组?如果按状态(您需要按状态进行分组以包含在谓词中),那么这不会折叠所有 OrderEntries 并且您不会获得单独的 objectID 和 orderCounts 吗?为此,最好坚持主要谓词,而不是分组和拥有谓词。
| 归档时间: |
|
| 查看次数: |
2060 次 |
| 最近记录: |