2009-12-30 4 views
3

J'utilise Fluent et NHibernate. J'ai deux objets disons A & B qui a une relation plusieurs-à-plusieurs entre eux. J'utilise un mappage plusieurs-à-plusieurs unidirectionnel lorsque A HasMany B's. Il n'y a pas de référence dans B sur A (unidirectionnel).Cascade lors de la suppression à l'aide du mappage un à plusieurs unidirectionnel

Cela crée une troisième table (nommée ABMapping) dans la base de données qui a les deux colonnes relatives aux clés primaires de A & B.

Si je supprime l'objet A, les entrées de la table ABMapping liés à A sont supprimés. C'est super. Mais, maintenant je ne suis pas en mesure de supprimer un objet B, car il a une contrainte FK. Comment puis-je le configurer de sorte que lors de la suppression de B, toutes les entrées relatives à B dans ABMapping sont supprimées automatiquement?

+0

La contrainte unidirectionnelle est-elle importante? Avec lui, à un niveau fondamental, vous devrez rechercher sur tous les mappages pour ceux liés à B pour chaque entrée dans B qui est supprimée. – Clueless

+0

Oui, la cartographie est importante. Et je veux éviter le scénario où, lors de la suppression de B, je dois supprimer les mappages sur B explicitement. Est-ce la seule façon d'y aller? En outre, que se passe-t-il pour un un-à-un unidirectionnel? Je pense que ce sera le même scénario. Si je supprime B, je devrai rechercher tous les objets de type A qui se réfèrent à B, et les supprimer d'abord avant de supprimer l'objet B. – Zuber

Répondre

1

Si B ne fait pas référence à A, il ne connaît pas la table de mappage et ne peut donc pas mettre en cascade la suppression. Comme je le vois, vous avez deux options:

  1. Cascade la suppression dans la base de données en utilisant des suppressions en cascade sur votre FK ou un déclencheur.
  2. Mapper la relation de B à A; vous n'avez pas à l'exposer aux consommateurs de votre classe, la collection A pourrait être mappée en tant que champ privé en utilisant une stratégie d'accès. Je fais toujours cela pour les collections (en utilisant .Access.CamelCaseField (Prefix.Underscore)) afin que je n'expose pas IList.
+0

Merci pour l'aide Jamie. Une autre question que j'ai maintenant est que si j'utilise le mappage bidirectionnel, puis supprimer un objet de classe B, il devrait seulement supprimer le mappage dans la table ABMapping. Cependant, lorsque j'ai essayé les paramètres Cascade en tant que .Delete ou .DeleteOnCascade, il disparaît et supprime également l'objet A. J'ai également eu un Inverse mis sur le mappage dans B. J'ai essayé Cascade.None() mais dans ce cas, il n'a pas supprimé le mappage dans ABMapping et m'a donné l'erreur de violation de contrainte. – Zuber

+0

@ Zuber - Ma réponse était incomplète. Vous ne devriez pas utiliser NH cascade avec beaucoup-à-plusieurs. Vous devez supprimer l'objet B de la collection de Bs de A (ceci supprime les liens), puis supprimer l'objet B. Je pense que si vous suivez cette route, vous n'aurez pas besoin de mapper la collection A en B, mais vous voudrez probablement faire référence aux objets A qui font référence à l'objet B. –

+0

@JamieIde que voulez-vous dire par "suppression en cascade sur votre FK?" Voulez-vous dire qu'il existe un moyen de dire à Hibernate/JPA de supprimer toutes les lignes avec des références FK pour un @ Entity avant de supprimer la ligne qui utilise le PK? (Parce que ce serait génial) Si vous voulez simplement dire 'Cascade.DELETE' sur la référence de' B' à 'A's, alors ce n'est pas intéressant car la suppression d'un' B' supprimerait aussi les lignes 'A'. – fommil

Questions connexes