ios 核心数据-如何获取具有最大值属性的实体

wixjitnu  于 2023-08-08  发布在  iOS
关注(0)|答案(7)|浏览(141)

我有一个实体Person,其属性为personId(personId是唯一的)
如何获取具有最大personId的Person?
(我想获取的是人本身,而不是财产的价值)

aiazj4mn

aiazj4mn1#

fetchLimit设置为1,并按personId降序排序。例如:

  1. NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
  2. fetchRequest.fetchLimit = 1;
  3. fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"personId" ascending:NO]];
  4. NSError *error = nil;
  5. id person = [managedObjectContext executeFetchRequest:fetchRequest error:&error].firstObject;

字符串

bz4sfanl

bz4sfanl2#

您需要使用带有NSPerdicate的NSFetchRequest来指定查询...
改编自Apple的同品种程序指南:

  1. NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
  2. NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person"
  3. inManagedObjectContext:managedObjectContext];
  4. [request setEntity:entity];
  5. request.predicate = [NSPredicate predicateWithFormat:@"personId==max(personId)"];
  6. request.sortDescriptors = [NSArray array];
  7. NSError *error = nil;
  8. NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];

字符串

lstz6jyr

lstz6jyr3#

建议使用Apple Recommended Method NSExpression。我希望这会比使用排序更便宜。如果你想一想,使用排序你将不得不把所有的记录排序,并保留最大的一个。对于表达式,您只需通读列表并在内存中保留最大值。
下面是我使用NSDate的一个示例

  1. - (NSDate *)lastSync:(PHAssetMediaType)mediaType {
  2. NSEntityDescription *entity = [NSEntityDescription entityForName:kMediaItemEntity inManagedObjectContext:self.managedObjectContext];
  3. NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  4. fetchRequest.entity = entity;
  5. fetchRequest.resultType = NSDictionaryResultType;
  6. NSMutableArray *predicates = [NSMutableArray array];
  7. [predicates addObject:[NSPredicate predicateWithFormat:@"%K=%d", kMediaType,mediaType]];
  8. [predicates addObject:[NSPredicate predicateWithFormat:@"%K=%d", kMediaProviderType,self.mediaProviderType]];
  9. NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates: predicates];
  10. fetchRequest.predicate = predicate;
  11. // Create an expression for the key path.
  12. NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:kSyncTime];
  13. // Create an expression to represent the function you want to apply
  14. NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:"
  15. arguments:@[keyPathExpression]];
  16. // Create an expression description using the maxExpression and returning a date.
  17. NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
  18. [expressionDescription setName:@"maxDate"];
  19. [expressionDescription setExpression:maxExpression];
  20. [expressionDescription setExpressionResultType:NSDateAttributeType];
  21. // Set the request's properties to fetch just the property represented by the expressions.
  22. fetchRequest.propertiesToFetch = @[expressionDescription] ; // @[kSyncTime];
  23. NSError *fetchError = nil;
  24. id requestedValue = nil;
  25. // fetch stored media
  26. NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError];
  27. if (fetchError || results == nil || results.count == 0) {
  28. return [NSDate dateWithTimeIntervalSince1970:0];
  29. }
  30. requestedValue = [[results objectAtIndex:0] valueForKey:@"maxDate"];
  31. if (![requestedValue isKindOfClass:[NSDate class]]) {
  32. return [NSDate dateWithTimeIntervalSince1970:0];
  33. }
  34. DDLogDebug(@"sync date %@",requestedValue);
  35. return (NSDate *)requestedValue;
  36. }

字符串

展开查看全部
00jrzges

00jrzges4#

上面使用NSExpression给出的答案是正确的。这是Swift版本。

  1. private func getLastSyncTimestamp() -> Int64? {
  2. let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest()
  3. request.entity = NSEntityDescription.entity(forEntityName: "EntityName", in: self.moc)
  4. request.resultType = NSFetchRequestResultType.dictionaryResultType
  5. let keypathExpression = NSExpression(forKeyPath: "timestamp")
  6. let maxExpression = NSExpression(forFunction: "max:", arguments: [keypathExpression])
  7. let key = "maxTimestamp"
  8. let expressionDescription = NSExpressionDescription()
  9. expressionDescription.name = key
  10. expressionDescription.expression = maxExpression
  11. expressionDescription.expressionResultType = .integer64AttributeType
  12. request.propertiesToFetch = [expressionDescription]
  13. var maxTimestamp: Int64? = nil
  14. do {
  15. if let result = try self.moc.fetch(request) as? [[String: Int64]], let dict = result.first {
  16. maxTimestamp = dict[key]
  17. }
  18. } catch {
  19. assertionFailure("Failed to fetch max timestamp with error = \(error)")
  20. return nil
  21. }
  22. return maxTimestamp
  23. }

字符串
其中moc是NSManagedObjectContext。

展开查看全部
mfuanj7w

mfuanj7w5#

Swift 3

  1. let request:NSFetchRequest = Person.fetchRequest()
  2. let sortDescriptor1 = NSSortDescriptor(key: "personId", ascending: false)
  3. request.sortDescriptors = [sortDescriptor1]
  4. request.fetchLimit = 1
  5. do {
  6. let persons = try context.fetch(request)
  7. return persons.first?.personId
  8. } catch {
  9. print(error.localizedDescription)
  10. }

字符串

展开查看全部
vsaztqbk

vsaztqbk6#

SWIFT 4

  1. let request: NSFetchRequest<Person> = Person.fetchRequest()
  2. request.fetchLimit = 1
  3. let predicate = NSPredicate(format: "personId ==max(personId)")
  4. request.predicate = predicate
  5. var maxValue: Int64? = nil
  6. do {
  7. let result = try self.context.fetch(request).first
  8. maxValue = result?.personId
  9. } catch {
  10. print("Unresolved error in retrieving max personId value \(error)")
  11. }

字符串

uubf1zoe

uubf1zoe7#

除了Ryan的回答,在今天的Swift中,NSManagedObjectexecute(_:)返回一个NSPersistentStoreResult对象,它需要一些额外的代码来检索值:

  1. // Cast `NSPersistentStoreResult` to `NSAsynchronousFetchResult<NSDictionary>`
  2. let fetchResult = moc.execute(request) as! NSAsynchronousFetchResult<NSDictionary>
  3. // Retrieve array of dictionary result
  4. let dictsResult = fetchResult.finalResult
  5. // Retrieve and cast the real result
  6. let key = /* `expressionDescription.name` */
  7. let result = dictsResult.first!.object(forKey: key) as! /* Your type, depending on `expressionDescription.expressionResultType` */

字符串

  • 注意:上面使用强制不安全类型转换来简化代码,在真实的情况下,您应该始终避免这种情况。*

相关问题