2008-10-12 6 views
1

J'ai des classes BidiParent et BidiChildList qui lient parents et enfants dans une relation parent-enfant bidirectionnelle. Si le parent d'un enfant est mis à jour par ex. la couche de service, les listes des enfants de l'ancien et du nouveau parents sont automatiquement mises à jour pour refléter le changement. De même, si la liste des enfants d'un parent est mise à jour par ex. l'ajout d'un nouvel enfant, le parent de l'enfant est automatiquement changé comme est la liste des enfants de l'ancien parent. Je veux essayer de construire un modèle de domaine "intelligent".Associations Bidi et mappage NHibernate

Première question, évidemment, est: est-ce même une bonne idée?

deuxième question est la suivante: est-il possible de dire NHibernate pour accéder et modifier le champ _Children ou _parent, mais de considérer les propriété enfants ou parents pour être tout à fait synonyme de terrain? Que NHibernate devrait charger et enregistrer les champs internes, mais les requêtes HQL ou LINQ devraient utiliser les propriétés publiques?

public class BidiParent<C, P> { ... } 

public class BidiChildList<C, P> : IList<C> { ... } 

public class Parent { 
    public string Name { get; set; } 
    public IList<Child> Children { 
     get { return ChildrenBidi; } 
     set { ChildrenBidi.Set(value); } 
    } 
    private BidiChildList<Child, Parent> ChildrenBidi { 
     get { return BidiChildList.Create(this, p => p._Children, c => c._Parent, (c, p) => c._Parent = p); } 
    } 
    internal IList<Child> _Children = new List<Child>(); 
} 

public class Child { 
    public string Name { get; set; } 
    public Parent Parent { 
     get { return ParentBidi.Get(); } 
     set { ParentBidi.Set(value); } 
    } 
    private BidiParent<Child, Parent> ParentBidi { 
     get { return BidiParent.Create(this, p => p._Children,() => _Parent, p => _Parent = p); } 
    } 
    internal Parent _Parent = null; 
} 

[Test] 
public void MultilevelConstruction_Succeeds() { 
    var p = new Parent { 
     Name = "Bob", 
     Children = new List<Child> { 
      new Child { Name = "Kate" }, 
      new Child { Name = "Billy" } 
     } 
    }; 
    Assert.AreEqual(2, p.Children.Count); 
    Assert.AreEqual("Kate", p.Children[0].Name); 
    Assert.AreEqual("Billy", p.Children[1].Name); 
    Assert.AreSame(p, p.Children[0].Parent); 
    Assert.AreSame(p, p.Children[1].Parent); 
} 

Répondre

1

répondre à ma propre question: je dois utiliser une stratégie de nommage, comme indiqué dans le docs. RTFM n'est-ce pas?

<class name="Parent"> 
    <property name="Name" /> 
    <bag name="Children" access="field.pascalcase-underscore"> 
     <key /> 
     <one-to-many class="Child" /> 
    </bag> 
</class> 
<class name="Child"> 
    <property name="Name" /> 
    <many-to-one name="Parent" access="field.pascalcase-underscore" /> 
</class> 
+0

Avez-vous déjà constaté des inconvénients à utiliser cette solution? – Rippo

+0

Parfois, je pense que "bugger" permet à ma clé étrangère d'être une colonne nullable que toute cette plomberie supplémentaire est alors redondante. – Rippo

Questions connexes