Комментарии 9
NSDictionary *productTotalSumAndAveragePriceGroupedByCountries =Это вместо обычного SQL-запроса?
[[[[[Product all
] aggregatedBy:@[
@[kAggregateSum, @«amount»],
@[kAggregatorAverage, @«price»]]
] groupedBy:@[@«country»]
] having:predicate
] execute];
Это вместо NSFetchRequest-а. Упомянутый вами request полностью эквивалентен
Но читать его легче, на мой взгляд.
NSFetchRequest *fetchRequest = [[ALFetchRequest alloc] init];
fetchRequest.managedObjectContext = managedObjectContext;
NSString *entityName = @"Product";
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesPendingChanges:YES];
// sum amount
NSExpression *fieldExp1 = [NSExpression expressionForKeyPath:@"amount"];
NSExpression *agrExp1 = [NSExpression expressionForFunction:agr arguments:@[fieldExp]];
NSExpressionDescription *resultDescription1 = [[NSExpressionDescription alloc] init];
NSString *resultName1 = @"sumAmount";
[resultDescription1 setName:resultName1];
[resultDescription1 setExpression:agrExp1];
[resultDescription1 setExpressionResultType:NSInteger64AttributeType];
// average price
NSExpression *fieldExp2 = [NSExpression expressionForKeyPath:@"price"];
NSExpression *agrExp2 = [NSExpression expressionForFunction:agr arguments:@[fieldExp]];
NSExpressionDescription *resultDescription2 = [[NSExpressionDescription alloc] init];
NSString *resultName2 = @"sumAmount";
[resultDescription2 setName:resultName2];
[resultDescription2 setExpression:agrExp2];
[resultDescription2 setExpressionResultType:NSInteger64AttributeType];
// country
NSDictionary *availableKeys = [entity attributesByName];
NSAttributeDescription *country = [availableKeys valueForKey:@"country"];
fetch.propertiesToFetch = [NSArray arrayWithObjects:country, resultDescription1, resultDescription2, nil];
fetch.propertiesToGroupBy = [NSArray arrayWithObject:country];
fetch.resultType = NSDictionaryResultType;
NSError *error;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:self error:&error];
if (!fetchedObjects || error) {
NSLog(@"Error: Execution of the fetchRequest: %@, Failed with Description: %@",self,error);
}
return fetchedObjects;
Но читать его легче, на мой взгляд.
Я просто немного не понимаю в чем тут «сахар», если есть язык SQL, на котором все это выглядит куда понятнее. И этому языку уже не один десяток лет.
Я довольно далек от iOS — разработки, наверное дело в том, что нельзя просто так взять и сделать SQL-запрос из данного приложения к этим данным?
Я довольно далек от iOS — разработки, наверное дело в том, что нельзя просто так взять и сделать SQL-запрос из данного приложения к этим данным?
Да, просто SQL запрос в CoreData сделать не получится. Но дело не только в этом.
В CoreData есть такая замечательная пара классов как NSFetchedResultsController и UITableViewController. Они очень оптимизированы и удобны в использовании. Так например, даже если в результате выполнения запроса мы получаем миллион записей, то FetchedResultsController загрузит в память только ту часть, которая видна из TableView. Если где-то в другом контроллере кто-то добавит, удалит или изменит содержимое отображаемых данных, то FRC автоматически стянет измененные данные в TableView с использованием приятных глазу анимаций.
В CoreData есть такая замечательная пара классов как NSFetchedResultsController и UITableViewController. Они очень оптимизированы и удобны в использовании. Так например, даже если в результате выполнения запроса мы получаем миллион записей, то FetchedResultsController загрузит в память только ту часть, которая видна из TableView. Если где-то в другом контроллере кто-то добавит, удалит или изменит содержимое отображаемых данных, то FRC автоматически стянет измененные данные в TableView с использованием приятных глазу анимаций.
Выгоды от CoreData не всегда могут быть столь однозначны. Можно к SQLite взять ActiveRecords или еще какой FMDB и количество кода для UITableViewContoller будет почти таким же, а запросы будут на чистом SQL.
Тут каждый решает сам в каждом конкретном кейсе.
Тут каждый решает сам в каждом конкретном кейсе.
По правде, я не использовал FMDB и интересно извещает ли он об изменениях. То есть, допустим я сделал селект всех продуктов, перешел на другой скрин и там добавил новый продукт. В первый TableView мне придет извещение, что данные изменились и их надо забрать?
Да, если Вы работаете только с sqlite. Но возможности CoreData намного шире чем работа только с одной базой данных.
=
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Запросы в CoreData с агрегатными функциями и группировкой в одну строку