Mam podmiot Person
z właściwością personId
(PersonID jest wyjątkowy)Rdzeń danych - Jak pobrać podmiot z max wartości nieruchomości
Jak mogę pobrać osoba z max PersonID?
(Chcę sprowadzić osobę sam nie wartość nieruchomości)
Mam podmiot Person
z właściwością personId
(PersonID jest wyjątkowy)Rdzeń danych - Jak pobrać podmiot z max wartości nieruchomości
Jak mogę pobrać osoba z max PersonID?
(Chcę sprowadzić osobę sam nie wartość nieruchomości)
można ustawić fetchLimit
do 1
i sortować według personId
w kolejności malejącej. Np:
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;
Musisz użyć NSFetchRequest z NSPredicate określić zapytanie ...
Adaptacja Apple predykatów progamming Przewodnik:
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];
Zalecanym sposobem jest użycie Apple Recommended Method NSExpression. Spodziewałbym się, że będzie to mniej kosztowne niż przy sortowaniu. Jeśli o tym pomyślisz, z pewnym rodzajem musiałbyś wziąć wszystkie rekordy, posortować je i zachować maksymalny. Z wyrażeniem musisz po prostu przeczytać listę i zachować w pamięci maksimum.
Oto przykład korzystać z 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;
}
To powinno być zaakceptowaną odpowiedzią. – shannoga
Wygląda na to, że podejście jest naprawdę najlepsze, ale wygląda na to, że nie działa w magazynie w pamięci: http://stackoverflow.com/questions/19301181/exception -rejestrowany przez-nse expressioniondescription-with-core-data-in-memory-store – oradyvan
To działało dla mnie, dopóki nie przeniosłem projektu do Swift 3. Apple, dla większego dobra, wprowadziło silnie typowane żądania pobierania, które nie działają z tym podejściem , powodując "Nie można rzucić wartość typu" NSKnownKeysDictionary1 "(0x106019870) na błąd" NSManagedObject "(0x106019b18).". Być może praca polega na użyciu metody 'execute' w MOC, ale wydaje się zbyt niski poziom i powrócę do metody" sortowania ". –
odpowiedzi udzielonej powyżej używając NSExpression jest poprawna. Oto wersja Swift.
private func getLastContactSyncTimestamp() -> Int64? {
let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest()
request.entity = NSEntityDescription.entity(forEntityName: "Contact", 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
}
gdzie moc jest NSManagedObjectContext.
Swift 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)
}
dzięki waszej pomocy – Eyal
Jeśli nie mają indeks atrybutu są sortowane, a następnie technika ta jest droższa, O (n log n), niż skanowanie listy za maksymalna wartość, O (n), jak opisano w odpowiedzi @ Uilleanna. To powiedziawszy, jeśli masz indeks na sortowanym atrybucie, obie techniki powinny być takie same. –
Czy warto ustawić 'fetchBatchSize' na 1, czy jest to niejawne w' fetchLimit' będącym 1? – Benjohn