2009-05-05 8 views
4

J'ai une classe Contact (classe de base), une classe appelée Customer et une classe appelée Supplier. Les clients et les fournisseurs proviennent tous deux de Contact.Comment mapper une collection <T> dans NHibernate?

Le client a une relation 0..n avec la commande. Je veux avoir une propriété Collection sur le client et l'avoir mappé dans NHibernate à sa table correspondante.

Comment cela se fait-il dans NHibernate (version 2.0.1 GA)?

(ps: en utilisant .NET 3.5 SP1, VS2008 SP1)

+0

Est-ce votre collection ordonnée? Je veux dire: attendez-vous les éléments dans le même ordre après le stockage et le retour de la base de données? –

+0

La collection doit être stockée de la manière dont j'ai ajouté des éléments. Ainsi, en ajoutant orderA, orderB, orderC et en le relisant, il doit contenir orderA, orderB et orderC dans cet ordre. –

Répondre

4

Cela se fait comme ceci:

Créez votre classe comme ceci:

public class Customer : Contact 
{ 
    private ISet<Order> _orders = new HashedSet<Order>(); 

    public Collection<Order> Orders 
    { 
     return new List<Order>(_orders); 
    } 

    // NOrmally I would return a ReadOnlyCollection<T> instead of a Collection<T> 
    // since I want to avoid that users add Orders directly to the collection. 
    // If your relationship is bi-directional, then you have to set the other 
    // end of the association as well, in order to hide this for the programmer 
    // I always create add & remove methods (see below) 

    public void AddOrder(Order o) 
    { 
     if(o != null && _orders.Contains(o) == false) 
     { 
     o.Customer = this; 
     _orders.Add(o); 
     } 
    } 
} 

dans votre cartographie, vous spécifiez cette :

<set name="Orders" table="OrdersTable" access="field.camelcase-underscore" inverse="true"> 
    <key column="..." /> 
    <one-to-many class="Order" .. /> 
</set> 

Depuis que vous utilisez l'héritage, vous devez certainement regarder les différentes possibilités s en ce qui concerne l'héritage-mapping NHibernate, et choisir la stratégie qui convient le mieux à votre situation: inheritance mapping

A propos du réglage & sémantique de sac: - lorsque vous associez une collection comme un ensemble, vous pouvez être sûr que tous les Les entités de la collection mappée sont uniques. C'est-à-dire que NHibernate s'assurera que, lors de la reconstitution d'une instance, la collection ne contiendra pas de doublons. - Lorsque vous mappez la collection en tant que sac, il est possible que votre collection contienne la même entité plus d'une fois lors du chargement de l'objet à partir de la base de données.

  • Un ensemble est une collection d'objets distincts considérés dans leur ensemble. Un exemple valide d'un ensemble de lettres ( ) est: {a, b, c, d}. Chaque lettre se produit exactement une fois.
  • Un sac est une généralisation d'un ensemble. Un membred'un sac peut avoir plus de un membre alors que chaque membre d'un ensemble n'a qu'un seul membre. Un exemple valide de sac est {a, a, a, b, c, c, d, ...}. Les lettres a et c apparaissent plus d'une fois dans le sac.
+0

Vous étiez plus rapide ... Description de l'héritage ici aussi - http://ayende.com/Blog/archive/2009/04/10/nhibernate-mapping-ndash-inheritance.aspx – Rashack

+0

J'utilise Collection dans mon exemple .. est-ce encore possible? –

+0

C'est toujours possible, mais dans mon exemple, le membre private _orders doit être de type ISet, car il est mappé en tant qu'ensemble. Si vous souhaitez que _orders soit une liste par exemple, vous devrez le mapper en tant que sac. (Mais les mappages de sac ont d'autres sémantiques que les set-mappings). Si vous modifiez le type de retour de la propriété Orders publique à collection ce n'est pas un problème (dans cet exemple), puisque la propriété publique n'est pas utilisée par NHibernate, mais le champ privé est (d'où l'attribut access dans le mapping) –

1

Une autre solution si vous ne souhaitez pas utiliser l'ensemble des collections Iesi

public class Customer : Contact 
{ 
    public ICollection<Order> Orders 
    { 
     get; private set; 

    } 
} 

Et la mise en correspondance comme ceci:

<bag name="Orders" table="Customer_Orders" > 
    <key column="Customer_FK" /> 
    <composite-element> 
    <property name="OrderNumber" /> 
    <property name="OrderName" /> 
    <!-- ... --> 
    </composite-element> 
</set> 
+1

encore mieux: http://feedproxy.google.com/~r/AyendeRahien/~3/etKiA3Njx-c/nhibernate-tidbit-ndash-using-ltsetgt-without-referencing-iesi.collections.aspx –

Questions connexes