iOS : 如何获取核心数据中最大计数的对象?
iOS : How to fetch objects with maximum count in core data?
我的核心数据模型中有两个 类,并且是一对多关系。
让我们以Class专辑<--->>Class歌曲来解释。现在我想从 Album
中获取(前)五张专辑,其中最大的 no.of Songs
.
Class Album
{
albumID (Integer)
name (String)
songs (class B)
}
Class Songs
{
name (String)
length (Integer)
}
@class Songs;
@interface Album : NSManagedObject
@property (nonatomic, retain) NSNumber * albumID;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *songs;
@end
@interface Album (CoreDataGeneratedAccessors)
- (void)addSongsObject:(Songs *)value;
- (void)removeSongsObject:(Songs *)value;
- (void)addSongs:(NSSet *)values;
- (void)removeSongs:(NSSet *)values;
@end
@class Album;
@interface Songs : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * length;
@property (nonatomic, retain) Album *owner;
@end
这是我正在尝试的,
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Albums" inManagedObjectContext:[self context]]];
fetchRequest.fetchOffset = 0;
fetchRequest.fetchLimit = 5;
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"albumID" ascending:YES]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SELF @max.@count.songs"];
NSError *error = nil;
NSArray *albums = [[self context] executeFetchRequest:fetchRequest error:&error];
如果我不传递谓词,它工作正常。但问题在于谓词。它使应用程序崩溃并显示以下消息:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format
string "SELF @max.@count.songs"'
Update:我正在对 NSExpression
进行同样的尝试,但无法同时执行 max:
和 count:
函数?下面是我试过的,
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Albums" inManagedObjectContext:[self context]]];
fetchRequest.fetchOffset = 0;
fetchRequest.fetchLimit = 5;
NSError *error = nil;
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"songs"];
NSExpression *countExpression = [NSExpression expressionForFunction:@"count:" arguments:[NSArray arrayWithObject:keyPathExpression]];
//NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:" arguments:[NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *maxCountExpressionDescription = [[NSExpressionDescription alloc] init];
[maxCountExpressionDescription setName:@"squishes"];
[maxCountExpressionDescription setExpression:countExpression];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:maxCountExpressionDescription]];
[fetchRequest setResultType:NSDictionaryResultType];
NSArray *albums = [[self context] executeFetchRequest:fetchRequest error:&error];
我想,我需要这样查询,
SELECT album.name, max(count(album.songs)) FROM Album;
如何在 NSFetchRequest
中创建这样的查询,是否可以使用 NSExpression
或 NSPredicate
?
尝试删除:
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SELF @max.@count.songs"];
并将您的排序描述符替换为:
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"songs.@count" ascending:NO]];
我用不同的方法解决了这个问题,我在相册 class 中添加了 songsCount
属性。每次我 add/remove 专辑中的歌曲时,我都会 incrementing/decrement 它。然后我获取所有按 songsCount
降序排序的专辑。
一旦我可以获取所有相册,我将运行一个for循环并取出前五个对象。
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Albums" inManagedObjectContext:[self context]]];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"songsCount" ascending:NO]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"songsCount > 0"];
NSError *error = nil;
NSArray *albums = [[self context] executeFetchRequest:fetchRequest error:&error];
NSMutableArray *top5Albums = [NSMutableArray array];
NSInteger totalCounts = [albums count];
NSInteger maxIndex = (totalCounts >= 5) ? 5 : totalCounts;
for(NSInteger index = 0; index < maxIndex; index++) {
[top5Albums addObject:[albums objectAtIndex:index]];
}
我的核心数据模型中有两个 类,并且是一对多关系。
让我们以Class专辑<--->>Class歌曲来解释。现在我想从 Album
中获取(前)五张专辑,其中最大的 no.of Songs
.
Class Album
{
albumID (Integer)
name (String)
songs (class B)
}
Class Songs
{
name (String)
length (Integer)
}
@class Songs;
@interface Album : NSManagedObject
@property (nonatomic, retain) NSNumber * albumID;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *songs;
@end
@interface Album (CoreDataGeneratedAccessors)
- (void)addSongsObject:(Songs *)value;
- (void)removeSongsObject:(Songs *)value;
- (void)addSongs:(NSSet *)values;
- (void)removeSongs:(NSSet *)values;
@end
@class Album;
@interface Songs : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * length;
@property (nonatomic, retain) Album *owner;
@end
这是我正在尝试的,
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Albums" inManagedObjectContext:[self context]]];
fetchRequest.fetchOffset = 0;
fetchRequest.fetchLimit = 5;
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"albumID" ascending:YES]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SELF @max.@count.songs"];
NSError *error = nil;
NSArray *albums = [[self context] executeFetchRequest:fetchRequest error:&error];
如果我不传递谓词,它工作正常。但问题在于谓词。它使应用程序崩溃并显示以下消息:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "SELF @max.@count.songs"'
Update:我正在对 NSExpression
进行同样的尝试,但无法同时执行 max:
和 count:
函数?下面是我试过的,
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Albums" inManagedObjectContext:[self context]]];
fetchRequest.fetchOffset = 0;
fetchRequest.fetchLimit = 5;
NSError *error = nil;
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"songs"];
NSExpression *countExpression = [NSExpression expressionForFunction:@"count:" arguments:[NSArray arrayWithObject:keyPathExpression]];
//NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:" arguments:[NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *maxCountExpressionDescription = [[NSExpressionDescription alloc] init];
[maxCountExpressionDescription setName:@"squishes"];
[maxCountExpressionDescription setExpression:countExpression];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:maxCountExpressionDescription]];
[fetchRequest setResultType:NSDictionaryResultType];
NSArray *albums = [[self context] executeFetchRequest:fetchRequest error:&error];
我想,我需要这样查询,
SELECT album.name, max(count(album.songs)) FROM Album;
如何在 NSFetchRequest
中创建这样的查询,是否可以使用 NSExpression
或 NSPredicate
?
尝试删除:
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SELF @max.@count.songs"];
并将您的排序描述符替换为:
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"songs.@count" ascending:NO]];
我用不同的方法解决了这个问题,我在相册 class 中添加了 songsCount
属性。每次我 add/remove 专辑中的歌曲时,我都会 incrementing/decrement 它。然后我获取所有按 songsCount
降序排序的专辑。
一旦我可以获取所有相册,我将运行一个for循环并取出前五个对象。
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Albums" inManagedObjectContext:[self context]]];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"songsCount" ascending:NO]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"songsCount > 0"];
NSError *error = nil;
NSArray *albums = [[self context] executeFetchRequest:fetchRequest error:&error];
NSMutableArray *top5Albums = [NSMutableArray array];
NSInteger totalCounts = [albums count];
NSInteger maxIndex = (totalCounts >= 5) ? 5 : totalCounts;
for(NSInteger index = 0; index < maxIndex; index++) {
[top5Albums addObject:[albums objectAtIndex:index]];
}