2010-11-04 2 views
1

J'ai un objet employeur qui peut avoir plusieurs personnes:Nhibernate supprimer des parents dans plusieurs à une relation entraînant la violation clé étrangère

//entities 
public class Person { 
    public virtual Guid Id {get;set;} 
    public virtual string Name {get;set;} 
    public virtual Employer CurrentEmployer {get;set;} 
} 

public class Employer { 
    public virtual Guid Id {get;set;} 
    public virtual string Name {get;set} 
    public virtual IList<Person> Employees {get;set;} 
} 

//person to employer mappings 
References(x => x.CurrentEmployer) 
    .Cascade.All() 
    .Column("CurrentEmployerId") 
    .ForeignKey("FK_Person_CurrentEmployer"); 

//employer to person mappings 
HasMany(x=> x.Employees) 
    .Inverse() 
    .Cascade.All(); 

Lorsque je tente de supprimer un employeur qui est lié à une personne, je obtenez une erreur "Foreign Key violation". Comment puis-je obtenir nHibernate pour annuler la colonne CurrentEmployerId avant la suppression de l'employeur?

Répondre

0

Avez-vous du code dispersé tout autour qui supprime les employeurs? Je pense normalement que vous ne disposez que d'une seule place dans le code qui supprime les employeurs, donc il n'y aurait pas vraiment besoin d'avoir nhibernate faire ce travail pour vous; Juste une déclaration là-bas qui met à jour tous les employés de référencement. Si ces suppressions sont effectivement dispersées, vous pouvez créer un intercepteur ou un écouteur d'événement qui a surveillé les suppressions de la table et faire référencer les mises à jour par intercepteur/écouteur.

+0

merci pour l'idée, mais une partie de mes exigences est que la suppression soit effectuée par nhibernate. – wusher

+0

Dans mes deux solutions, vous auriez toujours nhibernate effectuant la suppression; Dans le premier cas, votre code inclurait simplement une instruction de mise à jour avant la suppression, dans la seconde, l'intercepter/listener exécuterait l'instruction de mise à jour en réponse à l'apparition d'une suppression. –

1

essayer d'effacer d'abord de tout CurrentEmployer supprimer l'employé

public class Employer 
{ 
    public virtual Guid Id {get;set;} 
    public virtual string Name {get;set} 
    public virtual IList<Person> Employees {get;set;} 

    public void UnemployAll() 
    { 
     foreach(var employee in Employees) 
     { 
      employee.CurrentEmployer = null; 
     } 
     Employees = new List<Person>(); // clear it 
    } 
} 

puis essayez ce qui suit (je pense que devraient tous soient mis à jour les employés (personne)), je ne sais pas si cela va fonctionner sur le dessus de ma tête, mais cela peut vous aider à démarrer dans la bonne direction.

oldEmployer.UnemployAll(); 
_session.Delete(oldEmplorer); 
0

Essayez de le faire un

//employer to person mappings 
HasMany(x=> x.Employees) 
    .Inverse() 
    .Cascade.AllDeleteOrphan(); 

Je n'ai pas vérifié, mais j'espère que cela pourrait vous aider.

0

Oracle a la fonctionnalité de suppression en cascade (basée sur des contraintes de clé étrangère) intégrée. Sybase ne le fait pas. Selon si votre base de données prend en charge les déclencheurs avant et après, vous pouvez créer la fonctionnalité avec des déclencheurs avant. Sybase 12 n'a pas ça, il n'a que des triggers après, donc c'est impossible sur sybase. Sybase 15 a déjà des déclencheurs mais je ne l'ai pas encore essayé, mais ça devrait marcher, en gros vous écrivez manuellement le trigger avant pour faire la suppression en cascade.

Si cette fonctionnalité avant le déclenchement n'existe pas dans votre base de données, cela n'est pas possible. Vous devez d'abord supprimer par programme les lignes de la table enfant avant de supprimer les parents.

C'est comme ça.

+0

Merci, mais je n'essaie pas de faire des suppressions en cascade. J'essaie de supprimer une extrémité d'une relation un-à-plusieurs sans supprimer l'autre mais je reçois une erreur fk. – wusher

+0

Peut-être qu'il me manque quelque chose, mais il semble que vous essayez de violer la contrainte de clé étrangère. Si je lis correctement ce qui précède, la clé étrangère exige qu'il y ait un identifiant d'employeur dans la table de l'employeur pour chaque employeur mentionné dans la table des employés. Peut-être que je l'ai en arrière, pas un expert en hibernation, donc si vous essayez de supprimer l'employeur, vous devez vous assurer qu'il n'y a pas d'employés qui ont cette identification d'employeur avant de pouvoir supprimer l'employeur. Ahhh. Je vois.Vous avez posé cette même question. Je pense que je vais me dérober, je n'ai pas réalisé que c'était une question d'hibernation. Pardon. – stu

Questions connexes