2009-09-17 7 views
10

Dans mon projet iPhone, je souhaite écrire une fonction qui vérifie s'il existe un objet dans mes données de base ManagedObjectContext avec une valeur donnée pour une certaine propriété, par exemple some_property.Récupérer un objet par propriété dans les données de base

S'il existe déjà un objet avec some_property == 12, je souhaite que la fonction renvoie l'objet, sinon, je souhaite créer l'objet, ou au moins renvoyer nil.

Comment est-ce que je ferais cela?

Répondre

19

L'extrait suivant montre comment extraire les objets correspondant à un prédicat spécifique. S'il n'y a pas de tels objets, l'extrait montre comment créer un nouvel objet, l'enregistrer et le renvoyer.

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"YourEntityName" inManagedObjectContext:managedObjectContext]; 
    [request setEntity:entity]; 
    // retrive the objects with a given value for a certain property 
    NSPredicate *predicate = [NSPredicate predicateWithFormat: @"property == %@", value]; 
    [request setPredicate:predicate]; 

    // Edit the sort key as appropriate. 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"yourSortKey" ascending:YES]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
    [request setSortDescriptors:sortDescriptors]; 



    // Edit the section name key path and cache name if appropriate. 
    // nil for section name key path means "no sections". 
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"]; 
    aFetchedResultsController.delegate = self; 

    NSError *error = nil; 
    NSArray *result = [managedObjectContext executeFetchRequest:request error:&error]; 

    [request release]; 
    [sortDescriptor release]; 
    [sortDescriptors release]; 


    if ((result != nil) && ([result count]) && (error == nil)){ 
     return [NSMutableArray arrayWithArray:result]; 
    } 
    else{ 
     YourEntityName *object = (YourEntityName *) [NSEntityDescription insertNewObjectForEntityForName:@"YourEntityName" inManagedObjectContext:self.managedObjectContext]; 
      // setup your object attributes, for instance set its name 
      object.name = @"name" 

      // save object 
      NSError *error; 
      if (![[self managedObjectContext] save:&error]) { 
      // Handle error 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 

      } 

      return object; 

    } 
+0

wow, c'était rapide! Laissez-moi juste essayer cela ... – winsmith

+0

Quel est le point de 'aFetchedResultsController'? Est-ce que je me trompe en pensant que vous le créez, mais ne l'utilisez jamais pour faire quoi que ce soit? – ArtOfWarfare

+0

Vous avez raison, dans cet exemple particulier le NSFetchedResultsController n'est pas utilisé, mais il devrait être dans le contexte d'une application réelle (il simplifie beaucoup d'autres choses, et fournit un mécanisme de mise en cache agréable). –

2

Il est préférable de ne pas effectuer de chargement multiple si vous souhaitez vérifier certaines propriétés sur les données locales. Il suffit de faire une requête d'extraction en utilisant un tableau pré-rempli, puis d'itérer ou de filtrer les résultats.

C'est un extrait de code de programmation Guide de base de données "Implémentation Trouver-ou Créer Efficacement":

// get the names to parse in sorted order 
NSArray *employeeIDs = [[listOfIDsAsString componentsSeparatedByString:@"\n"] 
     sortedArrayUsingSelector: @selector(compare:)]; 

// create the fetch request to get all Employees matching the IDs 
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; 
[fetchRequest setEntity: 
     [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:aMOC]]; 
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(employeeID IN %@)", employeeIDs]]; 

// make sure the results are sorted as well 
[fetchRequest setSortDescriptors: [NSArray arrayWithObject: 
     [[[NSSortDescriptor alloc] initWithKey: @"employeeID" 
       ascending:YES] autorelease]]]; 
// Execute the fetch 
NSError *error; 
NSArray *employeesMatchingNames = [aMOC 
     executeFetchRequest:fetchRequest error:&error]; 
Questions connexes