2010-12-03 8 views
1

Je rencontre un problème avec la suppression de cascade de nhibernate fluide. Je suis sûr que je fais quelque chose de mal parce que ça ne marche pas.Fluent NHibernate cascade supprimer le problème

Voici mes objets:

public class Parent 
{ 
    public int Id { get; set; } 
    public IList<SequencedChild> SequencedChildren { get; set; } 
} 

public class SequencedChild 
{ 
    public int Id { get; set; } 
    public int ParentId { get; set; } 
    public int ChildId { get; set; } 
    public int Sequence { get; set; } 
} 

public class Child 
{ 
    public int Id { get; set; } 
} 

Et voici ma carte:

HasMany(m => m.SequencedChildren).Inverse().Cascade.Delete(); 

donc j'ai un parent avec des enfants séquencés et je veux mettre à jour ce parent de ne pas avoir d'enfants. Lorsque je fais une mise à jour sans enfants séquencés sur ce parent, je m'attends à ce que dans ma table SequencedChild les enregistrements qui ont l'ID du parent seront supprimés. Mais pour une raison quelconque NHibernate essaie de mettre à jour le ParentId de ces enregistrements avec null - qui échoue car ParentId n'est pas null. EDIT: Je m'attends également à ce que l'objet enfant ne soit pas affecté (qui se comporte correctement).

J'ai jeté un oeil à quelques questions et ils suggèrent tous l'utilisation de l'inverse mais je le fais déjà. Qu'est-ce que je fais mal?

Répondre

3

donc j'ai réussi à trouver une solution qui se est avéré avoir plusieurs étapes:

  1. Comme James a souligné dans un commentaire ParentId/ChildID devrait être parent/références d'enfants non seulement les ids (+1 pour ce
  2. SequencedChild doit avoir une mappe explicite qui définit la cascade à aucune
  3. Lors de la mise à jour, n'écrasez pas la liste SequencedChild. Commencez par effacer, puis ajoutez les nouveaux éléments. (Ou tout simplement clair si vous n'êtes pas remplacer les articles)
  4. L'appel Inverse() n'est pas nécessaire
  5. Le champ ParentId dans la table db doit être annulable parce que NHibernate insiste sur la mise à jour à null avant qu'elle ne le supprime. (si quelqu'un connaît un moyen de contourner cela laisser un commentaire)
+1

Salut, avez-vous essayé de marquer les références au parent avec Not.Nullable()? J'ai un scénario similaire au vôtre où j'ai ajouté Not.Nullable() aux références childs et cela crée la colonne comme NOT NULL. – Joe

+0

Merci pour ce heads-up, je ne pouvais pas non plus contourner la nécessité de rendre ma colonne de clé étrangère nulle, merci de m'avoir aidé à trouver où travailler. @Joe, bien que cela puisse créer la colonne comme non nulle, elle échoue toujours à l'exécution car nhibernate met à jour la ligne pour avoir un identifiant nul avant sa suppression. – kirps

+0

Pouvez-vous s'il vous plaît jeter un oeil à ma question http://stackoverflow.com/questions/22380027/flunet-nhibernate-mapping-cascade, je ne peux pas le faire fonctionner, on dirait que j'ai le même problème ... – MDDDC

1

Essayez de modifier la cascade en Cascade.AllDeleteOrphan() pour supprimer les enregistrements enfants orphelins de la table SequencedChild.

+0

Le problème est que les orphelins ne peuvent pas être créés puisque ParentId est NotNull et NHibernate essaie de les mettre à null. –

+0

Est-ce que votre classe SequencedChild a vraiment ParentId/ChildId plutôt que des références au parent/enfant? Si tel est le cas, Inverse() ne fonctionnera pas car vous dites à NHibernate que l'enfant gère la relation un-à-plusieurs, mais l'enfant n'a pas de référence arrière à son parent. NHibernate ne peut pas dire que ParentId (un int) est la référence arrière. –