NHibernate - Sammlungszuordnung

In diesem Kapitel werden wir uns mit der Darstellung von Sammlungen befassen. Es gibt verschiedene Arten von Sammlungen, die wir im NHibernate verwenden können, wie z.

  • Lists
  • Sets
  • Bags

Aus der .NET-Perspektive beschäftigen wir uns nun im Allgemeinen mit Listen oder ähnlichen sehr einfachen Datenstrukturen, Listen und Wörterbüchern. .NET verfügt nicht über eine Vielzahl unterschiedlicher Sammlungstypen. Warum braucht NHibernate all diese verschiedenen Typen? Es kommt wirklich auf die Datenbank zurück.

Liste

  • Eine Liste ist eine geordnete Sammlung von Elementen, die nicht unbedingt eindeutig sind.

  • Wir können dies mit dem abbilden IList <T>.

  • Obwohl wir herkömmlicherweise eine Liste mit Adressen haben und aus Sicht der Anwendung wissen, dass die Elemente eindeutig sind, hindert uns nichts in der Liste daran, doppelte Elemente in diese Liste einzufügen.

einstellen

  • Ein Set ist eine ungeordnete Sammlung einzigartiger Elemente. Wenn Sie versuchen, zwei doppelte Elemente in eine Menge einzufügen, wird eine Ausnahme ausgelöst.

  • In NHibernate gibt es nichts Spezielles.

  • Es ist nur eine bequeme Möglichkeit, eine generische Set-Implementierung zu haben. Wenn Sie mit .NET 4 arbeiten, können Sie das neue verwendenHashSet <T> Um diese darzustellen, stellen wir in den meisten NHibernate-Anwendungen dar, dass dies ein ISet ist.

  • Es ist ungeordnet, wenn Sie eine Liste von Adressen aus einer Datenbank oder eine Liste von Bestellungen zurückziehen, wissen Sie nicht, in welcher Reihenfolge sie eingehen, es sei denn, Sie geben eine bestimmte Order by-Klausel ein.

  • Im Allgemeinen sind die Daten, die Sie aus einer Datenbank zurückziehen, Mengen.

  • Sie sind einzigartige Sammlungen von Elementen, die ungeordnet sind.

Tasche

  • Eine weitere häufige Sammlung, die wir in der Datenbankwelt sehen werden, ist eine Tasche, die wie ein Set aussieht, nur dass sie doppelte Elemente enthalten kann.

  • In der .NET-Welt vertreten wir dies durch eine IList.

Sets sind wahrscheinlich die häufigsten, aber je nach Anwendung werden auch Listen und Taschen angezeigt. Werfen wir einen Blick in ein untencustomer.hbm.xml Datei aus dem letzten Kapitel, in dem Set Orders definiert sind.

<?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>

Wie Sie sehen, haben wir die Auftragserfassung als Satz zugeordnet. Denken Sie daran, dass ein Set eine ungeordnete Sammlung eindeutiger Elemente ist.

Wenn Sie sich nun die Kundenklasse ansehen, sehen Sie, dass die Orders-Eigenschaft mit einem ISet definiert ist, wie im folgenden Programm gezeigt.

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

Wenn diese Anwendung ausgeführt wird, wird die folgende Ausgabe angezeigt.

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...

Wenn die Artikel in der Sammlung nicht eindeutig sein müssen und mehrere Bestellungen mit demselben Primärschlüssel mehrmals in dieser Sammlung auftreten können, ist dies besser als Tasche zuzuordnen, wie im folgenden Programm gezeigt.

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

Wenn Sie diese Anwendung ausführen, wird eine Ausnahme angezeigt. Wenn wir uns die Kundenklasse ansehen, werden Sie feststellen, dass die Bestellungen im C # -Code als ISet markiert sind.

Wir müssen dies also auch in eine IList ändern, und dann müssten wir hier vom HashSet zu einer Liste im Konstruktor wechseln.

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(); 
   } 
}

Wenn Sie die Anwendung ausführen, sehen Sie dasselbe Verhalten. Jetzt können wir eine Bestellung mehrmals in derselben Sammlung haben.

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...