Fetch sur plusieurs entités (to-one)
IBimi
Membre
Bonjour,
J'ai besoin d'un éclaircissement concernant un fetch sur 2 entités (one to one).
J'ai plusieurs entités mais bon commençons juste avec 2: Person <---> Address (to-one)
Pour récupérer l'adresse d'une personne dont j'obtiens juste le nom via le tableView, je procède ainsi:
//Pour obtenir la personne
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entityPerson = [NSEntityDescription entityForName:@Person inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entityPerson];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@lastName = %@", personChoice];
NSArray *idClientArray = [detailMutableArray filteredArrayUsingPredicate:predicate];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@lastName ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSError *error = nil;
idClientArray = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
Pour obtenir l'adresse, est-ce que je peux procéder comme suit:
Person *person;
NSManagedObject *address = person.r_address;
//r_address est le nom de ma relation
Je récupère toujours une adresse "Null".
Pouvez-vous m'aider svp?
Merci
Mots clés:
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
En procédant ainsi tu risques d'avoir un problème si plusieurs personnes ont le même nom.
À quoi te sert :
Le code qui suit est douteux :
Il est instancié comment ton objet person ?
En fait detailMutablearray contient la liste de toutes les personnes mais maintenant que tu en parles c'est une information redondante.
J'ai voulu instancié mon objet personne comme ceci
Mais j'obtiens toujours une adresse Null.
Concernant :
Je dois faire un predicate sur le nom et sur le prénom alors c'est bien ça?
Merci
Pas vraiment. Dans ton premier post tu parles d'une table view où tu récupère juste le nom d'un personne. Je ne saisis pas vraiment : tu dois récupérer ce nom lors de la sélection d'une ligne de ta table view ? Si oui, pourquoi ne pas récupérer directement l'objet Person associé à l'index de sélection de ta table view ? Ca serait carrément plus simple !
Je dois récupérer ce nom pour pouvoir retrouver l'adresse par la suite mais je ne vois pas exactement ce que tu veux dire.
En fait je récupère la personne grâce l'index de la tableView et ensuite je passe le nom de cette personne à la vue détail.
Dans la vue détail j'effectue un fetchrequest avec un predicate dessus pour récupérer toutes les informations concernant cette personne à savoir: nom, prénom, âge, (adresse complète.....) ect.
Mais je n'arrive pas à récupérer l'adresse de cette personne.
Je pensais que récupérer les infos entre entités (one-to-one) était relativement simple...mais c'est pas mon cas. ::)
C'est un peu dommage alors que tu as l'objet Person représentant directement la personne cliquée, de ne passer que son nom au VC suivant et de demander au VC suivant de refaire un Fetch de son côté pour retomber si l'objet Person dont on est parti... sans compter comme te l'a mentionné Kubernan que du coup si tu as 2 personnes avec le même lastName et que tu ne passés que le lastName comme valeur pour retrouver la Person dans le 2e VC, si tu as 2 personnes VC le même lastName tu vas avoir des soucis... donc en plus de te compliquer la vie à faire Person -> lastName -> Person -> r_address, tu risques des incohérences, alors qu'il est tellement plus simple de faire juste Person -> r_address !!
Woaw... quelle économie de code en effet c'est bien mieux comme ça mais je n'arrive toujours pas à récupérer mon adresse.
L'adresse est toujours "Null", voici ce que j'obtiens en output:
data: {
age = 72;
birthDate = "1940-07-30 05:00:00 +0000";
email = "11111@hot.com";
firstName = Un;
gender = Homme;
lastName = Premier;
notes = nil;
objectif = "Bien \U00eatre personnel";
"r_idAddress" = nil;
"r_idMeasure" = nil;
"r_idRisko" = nil;
"r_idTelephone" = "<relationship fault: 0x81894c0 'r_idTelephone'>";
})
Toutes mes relations (one-to-one) sont à nil, est-ce normal?
Quant à ma relation "r_idTelephone" en fault c'est normal selon la doc(je ne vous apprends rien... ::) ).
Comment puis je maintenant obtenir l'adresse de cette personne sachant qu'elle a bien été enregistrée?
person.r_idAddress me renvoie Null.
Merci
Pourquoi les noms des valeurs qui ne marchent pas sont-elles entre guillemets, alors que le nom de celles qui marchent ne le sont pas ?
Simple coà¯ncidence c'est juste la console d'xcode qui met des guillemets autour des mots contenants un espace un - ou un _
Ah. OK. Je me disais qu'il pouvait y avoir du KVC un peu louche la dessous.
(Ou bien tu t'es imaginé que ça se faisait tout seul, ou via un champ type clé étrangère que tu aurais créé toi-même confondant CoreData avec une BDD)
Aaah... non je pensais que c'était géré par Core Data via les primary keys.
Et c'est donc juste avant la sauvegarde que je relie les données entre-elles?
Tu peux me montrer grossièrement un exemple?
Merci de votre aide
Mais le nom r_idAddress me paraà®t un peu louche. ça ne ressemble pas à un nom d'entité CoreData.
Non "r_idAddress" c'est ma relation en fait.
J'vais essayer ça...
Merci
- Pas besoin de déclarer une "Primary Key" toi-même (à la limite CoreData doit en gérer une tout seul comme un grand sous le capot, mais en pratique tu t'en fous)
- On ne parle pas de tables et de rangées, mais d'entités (NSEntity) et d'instances ou objets managés (NSManagedObjects). On ne parle pas de clés primaires et de clés étrangères, mais de relations, car dans CoreData tu indiques directement des Relationships entre des entités, alors que dans une BDD tu as besoin de te créer et gérer toi-même des clés primaires et étrangères pour implémenter ce concept de relation
- Du coup d'ailleurs, dans CoreData si tu veux une relation many-to-many, bah tu exprimes une relation many-to-many, et c'est tout (concrètement tu exprimes qu'il y a une relation to-many entre A et B, et une relation to-many entre B et A), et c'est CoreData qui s'arrange du reste. Alors que dans une BDD en général tu es obligé de gérer ça toi-même, créer même une table intermédiaire pour stocker les relations entre les clés étrangères des 2 tables à relier, et tout... mais ça CoreData s'en débrouille et fait ça pour toi.
Donc pour les relations dans CoreData, ce sont bien des relations toutes simples entre une entité et une autre entité, que tu décris. Comme une Personne a une Adresse (one-to-one). Ou un album de musique contient plusieurs pistes (one-to-many), etc. Exactement comme, en dehors de CoreData si tu créais des classes Objective-C classiques, tu aurais une "@property Address* r_address" dans ta classe "Person" (et certainement une "@property Person* r_person" dans ta classe "Address" pour avoir la relation inverse). D'ailleurs concrètement c'est comme ça que CoreData te le représente quand il génère les classes Objective-C correspondant à tes entités (NSEntity) CoreData. Il faut que tu fasses abstraction de l'aspect "Base de Données" et de l'aspect "besoin de gérer les relations soi-même et de créer des clés primaires et étrangères, voire de créer des tables intermédiaires, pour gérer les relations avec des jointures après", non, avec CoreData tout cela est transparent.
Yes bien compris et ça fonctionne autant pour les relations one-to-one que pour les relations one-to-many!!
D'une pierre deux coups car effectivement maintenant que j'ai relié mes objets, je peux également "deleter" tous mes objets en cascade ( cf. autre post).
Un grand MERCI à vous