MagicalRecord Delete With/Without Cascade

Salut tout l'monde.


 


MagicalRecord, ça a changé ma vie et mon avis sur CoreData, c'est sûr. Je remercie d'ailleurs au passage les mangeurs de Pomme qui me l'ont fait découvrir.

Bon, j'fais plus propre qu'avec CoreData tout seul, mais j'sais que j'peux encore largement progresser...


J'avoue avoir un peu de mal avec leur documentation.


 


Pour faire des requêtes, pas de soucis, elles sont assez simples, et j'ai eu un peu d'entraà®nement durant mes cours d'école sur du SQL, donc la logique, je l'ai. Celle de l'ajout et de la suppression, un peu moins, j'suis pas trop serein à  ce niveau-là .



Voici mon problème :


 


A contient un ou plusieurs B


B contient un ou plusieurs C, D et E.


 


J'aimerais supprimer B, C, D et E d'un coup.


Mon idée, c'est de faire une suppression en cascade, en mettant à  nil le lien entre A et B de B juste avant.

Est-ce une bonne pratique ?


Est-ce que cela va directement dire à  A que B n'existe plus (via sa mise à  nil) ?


Est-ce qu'il y a mieux ? Et plus propre ?


Réponses

  • AliGatorAliGator Membre, Modérateur
    Les Delete en cascade sont effectivement fait pour ça.

    ça se règle dans ton xcdatamodel.
  • Sauf erreur de ma part, si tu mets à  nil, tu indiques simplement que les objets ne sont plus liés. Ils ne sont pas détruits.


    Il faut faire un deleteObject (sur B) pour provoquer ton delete en cascade.


     


    Attention aux performances si tu as de gros volumes (le delete cascade nécessite la levée des faults).


  • LarmeLarme Membre
    janvier 2014 modifié #4
    Bon, ça n'a pas l'air de marcher comme je veux, alors j'vais demander quelques éclaircissements :
     
    Contexte :
    A possède plusieurs B.
    B possède plusieurs C, D et E. 
    Les liens décrits seront ainsi : lienDeAversB (A a en relationship lienDeAversB avec en destination B).
     
    But : Supprimer les B liés à  A, et les C,D,E liés à  B.
     
    Donc dans :
    lienDeBversC, je mets la Delete Rule à  Cascade.
    Leur lien inverse est à  Nullify.

    Je supprime B via deleteInContext
    Et je fais un saveToPersistentStoreAndWait à  la fin.
     
    Or, quand je fais ensuite un findAll en cherchant les B, C, D et E.
     
    Le nombre de B est bien changé. Mais le nombre de C, D et E, non.
     
     

    Apple indique ceci :

    Deny
    If there is at least one object at the relationship destination, then the source object cannot be deleted.
    For example, if you want to remove a department, you must ensure that all the employees in that department are first transferred elsewhere (or fired!) otherwise the department cannot be deleted.

    Nullify
    Set the inverse relationship for objects at the destination to null.
    For example, if you delete a department, set the department for all the current members to null. This only makes sense if the department relationship for an employee is optional, or if you ensure that you set a new department for each of the employees before the next save operation.

    Cascade
    Delete the objects at the destination of the relationship.
    For example, if you delete a department, fire all the employees in that department at the same time.

    No Action
    Do nothing to the object at the destination of the relationship.
    For example, if you delete a department, leave all the employees as they are, even if they still believe they belong to that department.


    Donc si j'ai bien tout suivi, mon erreur est sur les liens inverses (lienDeCversB, lienDeDversB et lienDeEversB) auquel je n'ai pas mis la bonne Delete Rule.
    Les exemples département/employés d'Apple sont sympa, mais j'ai dû mal avec la relation inverse et la Delete Rule.
    Car, la suppression de E, ne doit pas supprimer B.
    J'aurais tendance à  vouloir mettre un No Action. Est-ce juste ?
    Mais c'est étrange qu'avec un Cascade d'un côté (peut importe la relation derrière), cela n'implique pas leur suppression.
    Soit ça, soit j'ai fait une erreur dans mon code de suppression.


    ça me rappelle pourquoi je n'ai jamais aimé mes cours de BDD/SQL toute cette histoire.
  • Tes delete rules m'ont l'air OK. Tes relations inverses (B->A) sont to-one ou to-many ?


  • LarmeLarme Membre
    janvier 2014 modifié #6

    L'inverse est à  To One.


     


    B possède un ou plusieurs  C.

    C possède un unique B.


    Un 1-n (si mes souvenirs BDD sont bons).


     


     


     


    à‰dit :

    C'est bon, j'ai l'impression.

    J'ai dû déinstaller l'application et la réinstaller.


  • AliGatorAliGator Membre, Modérateur
    Ah oui quand on modifie le xcdatamodel faut en général penser à  faire un clean. Ou à  supprimer le fichier sqlite pour qu'il reconstruise les tables et le schéma correctement depuis zéro.

    (Ou alors fait faire un plan de migration en ajoutant une version à  ton datamodel mais bon ça c'est plutôt si t'as déjà  publié une V1 sur le store et veut faire une V2 avec des modifs de datamodel... pour les phases de dev on se contente de faire un clean et repartir d'une base propre tant qu'on l'a pas figée pour la release ;))


  • Ah oui quand on modifie le xcdatamodel faut en général penser à  faire un clean. Ou à  supprimer le fichier sqlite pour qu'il reconstruise les tables et le schéma correctement depuis zéro.




    Je retiens.

Connectez-vous ou Inscrivez-vous pour répondre.