Выражение для функции count в NSFetchRequest возвращает на единицу меньше, чем обычная выборка - PullRequest
1 голос
/ 09 декабря 2010

В моей первой попытке использовать NSExpression в запросе на выборку я получаю результат, который однозначно отличается от того, что я получаю, если использую обычный запрос на выборку.

МО «Субъект» имеет отношение ко многим с МО «Книгой», обратное отношение - к единице.

Это запрос выборки NSExpression, который я использую:

Project_AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@“Book”
                                                     inManagedObjectContext:context];
Subject *subjectToDelete = [self.arrayOfSubjects objectAtIndex:indexSelected];    
NSPredicate *pred = [NSPredicate predicateWithFormat:@"subject == %@", subjectToDelete];
NSExpression *expn = [NSExpression expressionForFunction:@"count:" 
                                                     arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:@"idPerm"]]];
NSExpressionDescription *expnDesc = [[NSExpressionDescription alloc] init];
[expnDesc setExpression:expn];
[expnDesc setName:@“countMatchingBooks”];
[expnDesc setExpressionResultType:NSInteger64AttributeType];
NSArray *properties = [NSArray arrayWithObject:expnDesc];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription]; 
[request setPredicate:pred];
[request setPropertiesToFetch:properties];
[request setResultType:NSDictionaryResultType];
NSError *error = nil; 
NSArray *results = [context executeFetchRequest:request error:&error];
if (error) {
    // error handling here
}
[request release];
[expnDesc release];

// Retrieve the count from the results array.
NSNumber *numBooksAssignedSubjectToDelete = [[results objectAtIndex:0] valueForKey:@“countMatchingBooks”];
uint64_t uloloBooksAssignedSubjectToDelete = [numBooksAssignedSubjectToDelete unsignedLongLongValue];

(Идея состоит в том, чтобы предоставить пользователю панель подтверждения, сообщающую ему о том, сколько книг будет удалено с помощью правила каскадирования, если они решат удалить выбранный объект - без сбоев МО книг на этом этапе.)

И это простой запрос fetch, который я использую в качестве теста:

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@“Book”
                                                     inManagedObjectContext:contextMain];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription]; 
NSError *error = nil; 
NSArray *booksAll = [contex executeFetchRequest:request error:&error];
[request release];
// Loop through the “booksAll” array and count those whose subject matches the one assigned as “subjectToDelete”

Что происходит, если NSExpression fetchRequest возвращает счетчик n, простой fetchRequest возвращает счетчик n + 1.

Думая, что сами запросы fetch могут каким-то образом изменять данные, я попытался запустить их в другом порядке, но с тем же результатом.

Может быть, запросы с использованием выражений пропускают МО, которые еще не были сохранены? Нет. Я запустил тест, который создает кучу новых «книжных» МО, чтобы посмотреть, увеличится ли разрыв между запросом выражения и обычным запросом. Осталось ровно одно.

Есть идеи, что я делаю не так?

1 Ответ

2 голосов
/ 24 февраля 2011

NSFetchRequests с использованием NSExpressionDescription не включает несохраненные объекты. NSFetchRequest имеет метод -setIncludePendingChanges:, который не принимает YES, если тип результата - NSDictionaryResultType. Это означает, что вы не можете использовать NSExpressionDescription для получения несохраненных объектов.

...