2016-10-29 3 views
0

мне нужно передать SQL запрос в Core Data:iOS CoreData. Группировка и маска

SELECT `quadkey`, MIN(id) AS id, COUNT(id) AS count, AVG(longitude) AS longitude, AVG(latitude) AS latitude 
FROM marker 
GROUP BY (quadkey & 15499683151872); 

мой код:

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"GBUserRoute"]; 
NSExpressionDescription *countExpressionDescription = [self expressionForFunction:@"count:" arguments:@[[NSExpression expressionForKeyPath:@"routeId"]] resultName:@"count" resultType:NSDoubleAttributeType]; 

NSExpressionDescription *minIdExpressionDescription = [self expressionForFunction:@"min:" arguments:@[[NSExpression expressionForKeyPath:@"routeId"]] resultName:@"minId" resultType:NSDoubleAttributeType]; 

NSExpressionDescription *averageLatitudeExpressionDescription = [self expressionForFunction:@"average:" arguments:@[[NSExpression expressionForKeyPath:@"latitude"]] resultName:@"latitude" resultType:NSDoubleAttributeType]; 

NSExpressionDescription *averageLongitudeExpressionDescription = [self expressionForFunction:@"average:" arguments:@[[NSExpression expressionForKeyPath:@"longitude"]] resultName:@"longitude" resultType:NSDoubleAttributeType]; 

NSExpressionDescription *minLongitudeExpressionDescription = [self expressionForFunction:@"min:" arguments:@[[NSExpression expressionForKeyPath:@"longitude"]] resultName:@"minLongitude" resultType:NSDoubleAttributeType]; 

NSExpressionDescription *minLatitudeExpressionDescription = [self expressionForFunction:@"min:" arguments:@[[NSExpression expressionForKeyPath:@"latitude"]] resultName:@"minLatitude" resultType:NSDoubleAttributeType]; 

NSExpressionDescription *maxLongitudeExpressionDescription = [self expressionForFunction:@"max:" arguments:@[[NSExpression expressionForKeyPath:@"longitude"]] resultName:@"maxLongitude" resultType:NSDoubleAttributeType]; 

NSExpressionDescription *maxLatitudeExpressionDescription = [self expressionForFunction:@"max:" arguments:@[[NSExpression expressionForKeyPath:@"latitude"]] resultName:@"maxLatitude" resultType:NSDoubleAttributeType]; 

NSExpressionDescription *groupExpressionDescription = [self expressionForFunction:@"bitwiseAnd:with:" arguments:@[[NSExpression expressionForKeyPath:@"quadKey"], [NSExpression expressionForConstantValue:@(15499683151872)]] resultName:@"quadKeyMask" resultType:NSInteger64AttributeType]; 

[fetchRequest setPropertiesToFetch:@[groupExpressionDescription, countExpressionDescription, minIdExpressionDescription, averageLongitudeExpressionDescription, averageLatitudeExpressionDescription, minLongitudeExpressionDescription, minLatitudeExpressionDescription, maxLongitudeExpressionDescription, maxLatitudeExpressionDescription]]; 
[fetchRequest setPropertiesToGroupBy:@[groupExpressionDescription]]; 
[fetchRequest setResultType:NSDictionaryResultType]; 

+ (NSExpressionDescription *)expressionForFunction:(NSString *)function arguments:(NSArray<NSExpression *> *)arguments resultName:(NSString *)resultName resultType:(NSAttributeType)resultType { 
NSExpression *expression = [NSExpression expressionForFunction: function 
                   arguments: arguments]; 
    NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; 
    [expressionDescription setName: resultName]; 
    [expressionDescription setExpression: expression]; 
    [expressionDescription setExpressionResultType: resultType]; 

    return expressionDescription; 
} 

При выполнении этого кода, я получаю следующее сообщение об ошибке:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid keypath expression ((), name quadKeyMask, isOptional 1, isTransient 0, entity (null), renamingIdentifier quadKeyMask, validation predicates ( ), warnings ( ), versionHashModifier (null) userInfo { }) passed to setPropertiesToFetch:'

+0

Основные данные не являются базой данных SQL. Это система сохранения объектов, которая * может * использовать SQLite в качестве хранилища объектов. – Paulw11

ответ

0

Во-первых, не видя вашей модели данных, мы не можем помочь вам отладить ваш запрос.

Ваша ошибка:

Invalid keypath expression ((), name quadKeyMask, isOptional 1, isTransient 0, entity (null), renamingIdentifier quadKeyMask, validation predicates (), warnings (), versionHashModifier (null) userInfo { }) passed to setPropertiesToFetch: 

указывает, что ключ интерпретатор путь не может следовать вашей модели данных. IOW, у вас есть ошибка в вашей сущности или выражении.

Ключом к перезаписи SQL-запросов в Core Data является понимание того, что они очень разные языки. Предикаты данных ядра задают операции выбора, используя критерии фильтра. Хотя это похоже на декларативный язык SQL, оно отличается. Концептуальные модели разные.

Мой совет: Перепишите свой запрос на мелкие кусочки. Так же, как вы могли бы отладить любую другую проблему. Сделайте мелкие кусочки; затем создайте небольшие комбинации ваших выражений. Разделите и победите.

Смежные вопросы