NHibernate - Cartographie des collections

Dans ce chapitre, nous expliquerons comment représenter les collections. Il existe différents types de collections que nous pouvons utiliser dans NHibernate tels que -

  • Lists
  • Sets
  • Bags

Maintenant, du point de vue .NET, nous traitons généralement des listes ou des structures de données très simples, des listes, des dictionnaires. .NET n'a pas une grande variété de types de collections différents. Alors pourquoi NHibernate a-t-il besoin de tous ces types différents? Cela revient vraiment à la base de données.

liste

  • Une liste est une collection ordonnée d'éléments qui ne sont pas nécessairement uniques.

  • Nous pouvons cartographier cela en utilisant le IList <T>.

  • Ainsi, bien que nous puissions classiquement avoir une liste d'adresses, et du point de vue de l'application, nous savons que les éléments sont uniques, rien dans la liste ne nous empêche d'insérer des éléments en double dans cette liste.

Ensemble

  • Un ensemble est une collection non ordonnée d'éléments uniques. Si vous essayez d'insérer 2 éléments en double dans un ensemble, cela lèvera une exception.

  • Il n'y a rien de spécifique dans NHibernate à ce sujet.

  • C'est juste un moyen pratique d'avoir une implémentation générique d'ensemble. Si vous utilisez .NET 4, vous pouvez utiliser le nouveauHashSet <T> pour les représenter, mais dans la plupart des applications NHibernate, nous représentons qu'il s'agit d'un ISet.

  • C'est un ordre non ordonné, si vous retirez une liste d'adresses d'une base de données ou d'une liste de commandes, vous ne savez pas dans quel ordre elles arrivent à moins que vous ne mettiez dans une clause Order by spécifique.

  • Donc, en général, les données que vous retirez d'une base de données sont des ensembles.

  • Ce sont des collections uniques d'éléments qui ne sont pas ordonnés.

Sac

  • Une autre collection courante que nous verrons dans le monde des bases de données est un sac, qui ressemble à un ensemble sauf qu'il peut avoir des éléments en double.

  • Dans le monde .NET, nous représentons cela par un IList.

Les ensembles sont probablement les plus courants, mais vous verrez également des listes et des sacs en fonction de votre application. Jetons un coup d'oeil dans un ci-dessouscustomer.hbm.xml fichier du dernier chapitre dans lequel les ordres de set sont définis.

<?xml version = "1.0" encoding = "utf-8" ?> 
<hibernate-mapping xmlns = "urn:nhibernate-mapping-2.2" assembly = "NHibernateDemo" 
   namespace = "NHibernateDemo"> 
	
   <class name = "Customer"> 
      
      <id name = "Id"> 
         <generator class = "guid.comb"/> 
      </id> 
   
      <property name = "FirstName"/> 
      <property name = "LastName"/> 
      <property name = "AverageRating"/> 
      <property name = "Points"/> 
      <property name = "HasGoldStatus"/> 
      <property name = "MemberSince" type = "UtcDateTime"/> 
      <property name = "CreditRating" type = "CustomerCreditRatingType"/>
      
      <component name = "Address"> 
         <property name = "Street"/> 
         <property name = "City"/> 
         <property name = "Province"/> 
         <property name = "Country"/> 
      </component>
      
      <set name = "Orders" table = "`Order`"> 
         <key column = "CustomerId"/> 
         <one-to-many class = "Order"/> 
      </set> 
   
   </class> 
</hibernate-mapping>

Comme vous pouvez le voir, nous avons mappé la collection de commandes comme un ensemble. N'oubliez pas qu'un ensemble est une collection non ordonnée d'éléments uniques.

Maintenant, si vous regardez la classe Customer, vous verrez que la propriété Orders est définie avec un ISet comme indiqué dans le programme suivant.

public virtual ISet<Order> Orders { get; set; }

Maintenant, lorsque cette application est exécutée, vous verrez la sortie suivante.

New Customer:
John Doe (00000000-0000-0000-0000-000000000000)
   Points: 100
   HasGoldStatus: True
   MemberSince: 1/1/2012 12:00:00 AM (Unspecified)
   CreditRating: Good
   AverageRating: 42.42424242

   Orders:
      Order Id: 00000000-0000-0000-0000-000000000000
      Order Id: 00000000-0000-0000-0000-000000000000

Reloaded:
John Doe (1f248133-b50a-4ad7-9915-a5b8017d0ff1)
   Points: 100
   HasGoldStatus: True
   MemberSince: 1/1/2012 12:00:00 AM (Utc)
   CreditRating: Good
   AverageRating: 42.4242

   Orders:
      Order Id: c41af8f2-7124-42a7-91c5-a5b8017d0ff6
      Order Id: 657f6bb0-1f42-45fc-8fc7-a5b8017d0ff7

The orders were ordered by:
John Doe (1f248133-b50a-4ad7-9915-a5b8017d0ff1)
   Points: 100
   HasGoldStatus: True
   MemberSince: 1/1/2012 12:00:00 AM (Utc)
   CreditRating: Good
   AverageRating: 42.4242

   Orders:
      Order Id: c41af8f2-7124-42a7-91c5-a5b8017d0ff6
      Order Id: 657f6bb0-1f42-45fc-8fc7-a5b8017d0ff7

John Doe (1f248133-b50a-4ad7-9915-a5b8017d0ff1)
   Points: 100
   HasGoldStatus: True
   MemberSince: 1/1/2012 12:00:00 AM (Utc)
   CreditRating: Good
   AverageRating: 42.4242

   Orders:
      Order Id: c41af8f2-7124-42a7-91c5-a5b8017d0ff6
      Order Id: 657f6bb0-1f42-45fc-8fc7-a5b8017d0ff7
		
Press <ENTER> to exit...

Si les éléments de la collection n'avaient pas besoin d'être uniques, si vous pouviez avoir plusieurs commandes avec la même clé primaire se produisant plusieurs fois dans cette collection, alors cela serait mieux mappé en tant que sac comme indiqué dans le programme suivant.

<bag name = "Orders" table = "`Order`"> 
   <key column = "CustomerId"/> 
   <one-to-many class = "Order"/> 
</bag>

Maintenant, si vous exécutez cette application, vous obtiendrez une exception car si nous examinons la classe client, vous remarquerez que les commandes sont marquées comme un ISet dans le code C #.

Nous devrons donc également changer cela en IList, puis ici, nous aurions besoin de passer du HashSet à une liste dans le constructeur.

public class Customer { 

   public Customer() { 
      MemberSince = DateTime.UtcNow; 
      Orders = new List<Order>(); 
   } 
	
   public virtual Guid Id { get; set; } 
   public virtual string FirstName { get; set; } 
   public virtual string LastName { get; set; } 
   public virtual double AverageRating { get; set; } 
   public virtual int Points { get; set; } 
	
   public virtual bool HasGoldStatus { get; set; } 
   public virtual DateTime MemberSince { get; set; } 
   public virtual CustomerCreditRating CreditRating { get; set; } 
   public virtual Location Address { get; set; }
   public virtual IList<Order> Orders { get; set; }
   public virtual void AddOrder(Order order) { Orders.Add(order); order.Customer = this; }
   
   public override string ToString() { 
      var result = new StringBuilder(); 
		
      result.AppendFormat("{1} {2} ({0})\r\n\tPoints: {3}\r\n\tHasGoldStatus:
         {4}\r\n\tMemberSince: {5} ({7})\r\n\tCreditRating: {6}\r\n\tAverageRating:
         {8}\r\n", Id, FirstName, LastName, Points, HasGoldStatus, MemberSince,
         CreditRating, MemberSince.Kind, AverageRating); result.AppendLine("\tOrders:"); 
      
      foreach(var order in Orders) { 
         result.AppendLine("\t\t" + order); 
      } 
		
      return result.ToString(); 
   } 
}

Lorsque vous exécutez l'application, vous verrez le même comportement. Mais, maintenant, nous pouvons avoir une commande se produisant plusieurs fois dans la même collection.

John Doe (00000000-0000-0000-0000-000000000000)
   Points: 100
   HasGoldStatus: True
   MemberSince: 1/1/2012 12:00:00 AM (Unspecified)
   CreditRating: Good
   AverageRating: 42.42424242

   Orders:
      Order Id: 00000000-0000-0000-0000-000000000000
      Order Id: 00000000-0000-0000-0000-000000000000

Reloaded:
John Doe (fbde48f5-d620-4d1c-9a7f-a5b8017c3280)
   Points: 100
   HasGoldStatus: True
   MemberSince: 1/1/2012 12:00:00 AM (Utc)
   CreditRating: Good
   AverageRating: 42.4242

   Orders:
      Order Id: 6dd7dbdb-354f-4c82-9c39-a5b8017c3286
      Order Id: 9b3e2441-a81b-404d-9aed-a5b8017c3287

The orders were ordered by:
John Doe (fbde48f5-d620-4d1c-9a7f-a5b8017c3280)
   Points: 100
   HasGoldStatus: True
   MemberSince: 1/1/2012 12:00:00 AM (Utc)
   CreditRating: Good
   AverageRating: 42.4242

   Orders:
      Order Id: 6dd7dbdb-354f-4c82-9c39-a5b8017c3286
      Order Id: 9b3e2441-a81b-404d-9aed-a5b8017c3287

John Doe (fbde48f5-d620-4d1c-9a7f-a5b8017c3280)
   Points: 100
   HasGoldStatus: True
   MemberSince: 1/1/2012 12:00:00 AM (Utc)
   CreditRating: Good
   AverageRating: 42.4242

   Orders:
      Order Id: 6dd7dbdb-354f-4c82-9c39-a5b8017c3286
      Order Id: 9b3e2441-a81b-404d-9aed-a5b8017c3287
		
Press <ENTER> to exit...