2009-08-24 9 views
6

Je suis en train de créer une classe auto-référencée. Un enfant a une référence à son parent et un parent a une liste d'enfants. Puisque la liste des enfants est ordonnée, j'essaye de mapper la relation en utilisant NHibernate.Nhibernate - La liste de mappage ne met pas à jour les index de la liste

Ceci est mon application:

<class name="MyClass"> 
    <id name="Id"> 
    <generator class="native"/> 
    </id> 
    <list name="Children" cascade="delete" inverse="true"> 
    <key column="ParentId"/> 
    <index column="ListOrder"/> 
    <one-to-many class="MyClass"/> 
    </list> 
    <many-to-one name="Parent" class="MyClass" column="ParentId"/> 
</class> 

Le problème que je vais avoir est quand avoir un enfant de cartographie bidirectionnelle < -> parent, l'indice de la liste (ListOrder) ne sont pas mis à jour dans la base de données lorsque Je fais ma danse CRUD. Cela signifie que lorsque je par ex. supprimer un enfant, je reçois des trous dans la liste des enfants après avoir enregistré dans la base de données et récupérer le parent à nouveau. Si je supprime la bidirectionnalité, en n'ayant pas un multiple à un des enfants au parent (et pas inverse = true), le ListOrder est mis à jour correctement.

Avez-vous déjà vu cela auparavant? Y a-t-il une solution simple?

+0

son à cause de l'inverse = true, pas sûr de ce que la meilleure solution est encore, ayant exactement la même question pour le moment. restez à l'écoute –

+0

Yup, c'est à cause de l'inverse = vrai. Si le bidir est supprimé, tout fonctionne comme je le souhaite, ListOrder. La chose est que je dois implémenter la propriété des enfants moi-même, ce que je ne veux pas. –

Répondre

5

Oui, en raison de l'inverse = true, une solution alternative serait d'utiliser un ensemble ou un sac au lieu de list avec order = "ListOrder", ajouter la colonne ListOrder en tant que propriété à la classe MyClass avec un setter vide et un getter qui retourne toujours son index de la collection enfant de son parent. Comme ceci:

<class name="MyClass"> 
    <id name="Id"> 
     <generator class="native"/> 
    </id> 
    <bag name="Children" cascade="delete" inverse="true" order-by="ListOrder"> 
     <key column="ParentId"/> 
     <one-to-many class="MyClass"/> 
    </bag> 
    <property name="ListOrder" column="ListOrder"/> 
    <many-to-one name="Parent" class="MyClass" column="ParentId"/> 
</class> 

et la classe

public class MyClass 
{ 
    public virtual int ID { get; set; } 
    public virtual IList<MyClass> Children { get; set; } 
    public virtual MyClass Parent { get; set; } 

    public virtual int ListOrder 
    { 
     get 
     { 
      if (Parent == null || !Parent.Children.Contains(this)) return -1; 
      return Parent.Children.IndexOf(this); 
     } 
     set { } 
    } 
} 
+3

Merci pour votre suggestion. Dans mon code aujourd'hui, j'utilise des crochets lors de l'ajout/suppression d'enfants pour définir le ListOrder correctement. Je travaille fondamentalement autour de NHibernate ne fonctionnant pas comme je l'espère en ajoutant la logique dans mon domaine. Votre suggestion est une autre solution de contournement de la couche de domaine. C'est peut-être mieux que le mien, mais toujours une solution de contournement. Si la sémantique de ma liste est une liste, je veux la mapper comme une liste, pas comme un sac trié. –

+0

J'aime l'idée de votre propriété –