ios 核心数据 - 如何获取具有最大值属性的实体
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10398019/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Core Data - How to fetch an entity with max value property
提问by Eyal
I have a entity Person
with a property personId
(personId is unique)
我有一个Person
带有属性的实体personId
(personId 是唯一的)
How can I fetch the Person with the max personId?
如何获取具有最大 personId 的 Person?
(I want to fetch the person itself not the value of the property)
(我想获取人本身而不是财产的价值)
回答by hypercrypt
You set the fetchLimit
to 1
and sort by personId
in descending order. E.g.:
您设置fetchLimit
to1
并按personId
降序排序。例如:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
fetchRequest.fetchLimit = 1;
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"personId" ascending:NO]];
NSError *error = nil;
id person = [managedObjectContext executeFetchRequest:fetchRequest error:&error].firstObject;
回答by Uilleann
You need to use a NSFetchRequest with a NSPredicate to specify your query...
您需要使用带有 NSPredicate 的 NSFetchRequest 来指定您的查询...
Adapted from Apple's Predicate Progamming Guide :
改编自 Apple 的 Predicate Progamming Guide :
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person"
inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
request.predicate = [NSPredicate predicateWithFormat:@"personId==max(personId)"];
request.sortDescriptors = [NSArray array];
NSError *error = nil;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
回答by Ryan Heitner
The recommended way is to use Apple Recommended MethodNSExpression. I would expect that this would be less expensive than using a sort.If you think about it, with a sort you would have to take all the records sort them and keep the maximum one. With an expression you would just have to read through the list and keep in memory the maximum.
推荐的方法是使用Apple 推荐的方法NSExpression。我希望这比使用排序更便宜。如果您考虑一下,使用排序您必须对所有记录进行排序并保留最大一个。使用表达式,您只需通读列表并最大程度地保留在内存中。
Here is an example I use with NSDate
这是我与 NSDate 一起使用的示例
- (NSDate *)lastSync:(PHAssetMediaType)mediaType {
NSEntityDescription *entity = [NSEntityDescription entityForName:kMediaItemEntity inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = entity;
fetchRequest.resultType = NSDictionaryResultType;
NSMutableArray *predicates = [NSMutableArray array];
[predicates addObject:[NSPredicate predicateWithFormat:@"%K=%d", kMediaType,mediaType]];
[predicates addObject:[NSPredicate predicateWithFormat:@"%K=%d", kMediaProviderType,self.mediaProviderType]];
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates: predicates];
fetchRequest.predicate = predicate;
// Create an expression for the key path.
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:kSyncTime];
// Create an expression to represent the function you want to apply
NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:"
arguments:@[keyPathExpression]];
// Create an expression description using the maxExpression and returning a date.
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName:@"maxDate"];
[expressionDescription setExpression:maxExpression];
[expressionDescription setExpressionResultType:NSDateAttributeType];
// Set the request's properties to fetch just the property represented by the expressions.
fetchRequest.propertiesToFetch = @[expressionDescription] ; // @[kSyncTime];
NSError *fetchError = nil;
id requestedValue = nil;
// fetch stored media
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError];
if (fetchError || results == nil || results.count == 0) {
return [NSDate dateWithTimeIntervalSince1970:0];
}
requestedValue = [[results objectAtIndex:0] valueForKey:@"maxDate"];
if (![requestedValue isKindOfClass:[NSDate class]]) {
return [NSDate dateWithTimeIntervalSince1970:0];
}
DDLogDebug(@"sync date %@",requestedValue);
return (NSDate *)requestedValue;
}
回答by jarora
The answer given above using NSExpression is correct. Here is the Swift version.
上面使用 NSExpression 给出的答案是正确的。这是 Swift 版本。
private func getLastSyncTimestamp() -> Int64? {
let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest()
request.entity = NSEntityDescription.entity(forEntityName: "EntityName", in: self.moc)
request.resultType = NSFetchRequestResultType.dictionaryResultType
let keypathExpression = NSExpression(forKeyPath: "timestamp")
let maxExpression = NSExpression(forFunction: "max:", arguments: [keypathExpression])
let key = "maxTimestamp"
let expressionDescription = NSExpressionDescription()
expressionDescription.name = key
expressionDescription.expression = maxExpression
expressionDescription.expressionResultType = .integer64AttributeType
request.propertiesToFetch = [expressionDescription]
var maxTimestamp: Int64? = nil
do {
if let result = try self.moc.fetch(request) as? [[String: Int64]], let dict = result.first {
maxTimestamp = dict[key]
}
} catch {
assertionFailure("Failed to fetch max timestamp with error = \(error)")
return nil
}
return maxTimestamp
}
where moc is a NSManagedObjectContext.
其中 moc 是一个 NSManagedObjectContext。
回答by Rajat Jain
Swift 3
斯威夫特 3
let request:NSFetchRequest = Person.fetchRequest()
let sortDescriptor1 = NSSortDescriptor(key: "personId", ascending: false)
request.sortDescriptors = [sortDescriptor1]
request.fetchLimit = 1
do {
let persons = try context.fetch(request)
return persons.first?.personId
} catch {
print(error.localizedDescription)
}
回答by hamada147
SWIFT 4
快速 4
let request: NSFetchRequest<Person> = Person.fetchRequest()
request.fetchLimit = 1
let predicate = NSPredicate(format: "personId ==max(personId)")
request.predicate = predicate
var maxValue: Int64? = nil
do {
let result = try self.context.fetch(request).first
maxValue = result?.personId
} catch {
print("Unresolved error in retrieving max personId value \(error)")
}