Учебники

NHibernate — Отображение коллекции

В этой главе мы рассмотрим, как представлять коллекции. Существуют различные типы коллекций, которые мы можем использовать в NHibernate, такие как —

  • Списки
  • наборы
  • мешки

Теперь, с точки зрения .NET, мы обычно имеем дело со списками или как с очень простыми структурами данных, списками, словарями. .NET не имеет большого разнообразия типов коллекций. Так зачем NHibernate все эти разные типы? Это действительно возвращается в базу данных.

Список

  • Список — это упорядоченная коллекция элементов, которые не обязательно являются уникальными.

  • Мы можем отобразить это, используя IList <T> .

  • Таким образом, хотя у нас может быть обычный список адресов, и с точки зрения приложения мы знаем, что элементы уникальны, ничто в списке не мешает нам вставлять повторяющиеся элементы в этот список.

Список — это упорядоченная коллекция элементов, которые не обязательно являются уникальными.

Мы можем отобразить это, используя IList <T> .

Таким образом, хотя у нас может быть обычный список адресов, и с точки зрения приложения мы знаем, что элементы уникальны, ничто в списке не мешает нам вставлять повторяющиеся элементы в этот список.

Задавать

  • Набор — это неупорядоченная коллекция уникальных элементов. Если вы попытаетесь вставить 2 повторяющихся элемента в набор, это вызовет исключение.

  • В NHibernate нет ничего конкретного.

  • Это просто удобный способ иметь реализацию общего набора. Если вы используете .NET 4, вы можете использовать новый HashSet <T> для их представления, но в большинстве приложений NHibernate мы представляем, что это ISet.

  • Это неупорядоченный, если вы извлекаете список адресов из базы данных или список заказов, вы не знаете, в каком порядке они поступают, если вы не добавите конкретный пункт Order by.

  • В общем, данные, которые вы извлекаете из базы данных, являются наборами.

  • Это уникальные коллекции неупорядоченных элементов.

Набор — это неупорядоченная коллекция уникальных элементов. Если вы попытаетесь вставить 2 повторяющихся элемента в набор, это вызовет исключение.

В NHibernate нет ничего конкретного.

Это просто удобный способ иметь реализацию общего набора. Если вы используете .NET 4, вы можете использовать новый HashSet <T> для их представления, но в большинстве приложений NHibernate мы представляем, что это ISet.

Это неупорядоченный, если вы извлекаете список адресов из базы данных или список заказов, вы не знаете, в каком порядке они поступают, если вы не добавите конкретный пункт Order by.

В общем, данные, которые вы извлекаете из базы данных, являются наборами.

Это уникальные коллекции неупорядоченных элементов.

Мешок

  • Еще одна распространенная коллекция, которую мы увидим в мире баз данных, — это сумка, которая похожа на набор, за исключением того, что в ней могут быть повторяющиеся элементы.

  • В мире .NET мы представляем это как IList.

Еще одна распространенная коллекция, которую мы увидим в мире баз данных, — это сумка, которая похожа на набор, за исключением того, что в ней могут быть повторяющиеся элементы.

В мире .NET мы представляем это как IList.

Наборы, вероятно, самые распространенные, но вы также увидите списки и пакеты в зависимости от вашего приложения. Давайте посмотрим на файл customer.hbm.xml, приведенный ниже, из последней главы, в которой определены заказы Set.

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

Как видите, мы сопоставили коллекцию заказов как набор. Помните, что набор — это неупорядоченная коллекция уникальных элементов.

Теперь, если вы посмотрите на класс Customer, вы увидите, что свойство Orders определяется ISet, как показано в следующей программе.

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

Теперь, когда это приложение запущено, вы увидите следующий вывод.

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

Если элементы в коллекции не должны быть уникальными, если у вас может быть несколько заказов с одним и тем же первичным ключом, встречающимся несколько раз в этой коллекции, тогда это будет лучше сопоставлено как пакет, как показано в следующей программе.

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

Теперь, если вы запустите это приложение, вы получите исключение, потому что если мы посмотрим на класс клиента, вы заметите, что заказы помечены как ISet в коде C #.

Таким образом, нам также нужно будет изменить это значение на IList, а затем нам нужно будет перейти от HashSet к списку в конструкторе.

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

Когда вы запустите приложение, вы увидите то же поведение. Но теперь у нас может быть порядок, встречающийся несколько раз в одной коллекции.