按实体描述过滤核心数据

时间:2014-09-24 17:11:40

标签: ios objective-c sqlite core-data

我有一个非常大的CoreData表,其元素如下(简化):

@interface Medicament : NSManagedObject
@property (nonatomic, retain) NSString * identifier;
@property (nonatomic, retain) NSString * name;
@end

在某些时候我想找到具有相同属性的元素(并丢弃其余的属性),类似这样的SQLite句子:

SELECT name, COUNT(*) AS count FROM Medicament GROUP BY name WHERE count > 1

为此,我有这个CoreData查询:

NSFetchRequest* fetch = [NSFetchRequest fetchRequestWithEntityName:@"Medicament"];
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Medicament"
                                          inManagedObjectContext:self.managedObjectContext];
NSAttributeDescription* identifierDesc = [entity.attributesByName objectForKey:@"identifier"];
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"identifier"];
NSExpression *countExpression = [NSExpression expressionForFunction: @"count:"
                                                          arguments: [NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName: @"count"];
[expressionDescription setExpression: countExpression];
[expressionDescription setExpressionResultType: NSInteger32AttributeType];


[fetch setPropertiesToFetch:[NSArray arrayWithObjects:identifierDesc, expressionDescription, nil]];
[fetch setPropertiesToGroupBy:[NSArray arrayWithObject:identifierDesc]];
[fetch setResultType:NSDictionaryResultType];
NSError* error = nil;
NSArray *results = [self.managedObjectContext executeFetchRequest:fetch
                                                         error:&error];

这似乎正确地返回了具有以下格式的字典列表:

{
    count = 1;
    identifier = 65023;
},
    {
    count = 2;
    identifier = 65025;
},
{
    count = 1;
    identifier = 65027;
}

问题是,我想放弃count等于1的所有结果。

我尝试在fetch中添加一个谓词,希望CoreData足够聪明,这样:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"count > 1"];
fetch.predicate = predicate;

但它因错误keypath count not found in entity <NSSQLEntity Medicament id=11>而崩溃。

甚至可以使用CoreData,还是必须在从数据库中提取后过滤结果?


这是我目前用于过滤已从数据库加载的对象的方法:

NSPredicate* filterPredicate = [NSPredicate predicateWithFormat:@"count > 1"];
NSArray* filteredResults = [results filteredArrayUsingPredicate:filterPredicate];

但我希望这个简单的计算可​​以由CoreData或SQLite执行,这可能会更有效率。

1 个答案:

答案 0 :(得分:0)

你能做到这一点的唯一方法是首先获取数据,然后从那里按计数过滤它。

如果您需要,可以向名为count的实体添加属性,然后您可以使用该谓词来过滤所需的实体(在本例中为count&gt; 1),但您需要在Medicament中添加count属性这样做的实体。