Mapping collections of elements and components

So far, we've shown how to use collections where an entity relates to a set of other entitities. However, a collection can also hold simple values, such as strings or components, that is, objects with properties but no id.

Getting ready

Complete the Getting ready instructions at the beginning of this chapter.

How to do it…

  1. Add a new folder named ComponentCollections to the MappingRecipes project.
  2. Add a new class named Customer to the folder:
    public class Customer
    {
        public Customer()
        {
            Addresses=new List<Address>();
            Tags=new HashSet<string>();
        }
        public virtual Guid Id { get; protected set; }
        public virtual string Name { get; set; }
        public virtual IList<Address> Addresses { get; set; }
        public virtual ISet<string> Tags { get; set; }
    }
  3. Add a new class named Address to the folder:
    public class Address
    {
        public string AddressLine1 { get; set; }
        public string AddressLine2 { get; set; }
        public string City { get; set; }
        public string PostalCode { get; set; }
    }
  4. Add an embedded mapping named Customer.hbm.xml to the folder:
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
        assembly="MappingRecipes"
        namespace="MappingRecipes.ComponentCollections">
        <class name="Customer">
            <id name="Id">
                <generator class="guid.comb"/>
            </id>
            <property name="Name"/>
            <list name="Addresses" table="CustomerAddress">
                <key column="CustomerId"/>
                <index column="AddressIndex"/>
                <composite-element class="Address">
                    <property name="AddressLine1"/>
                    <property name="AddressLine2"/>
                    <property name="City"/>
                    <property name="PostalCode"/>
                </composite-element>
            </list>
            <set name="Tags" table="CustomerTag">
                <key column="CustomerId"/>
                <element column="Tag" type="string"/>
            </set>
        </class>
    </hibernate-mapping>
  5. Add a new class named Recipe to the folder:
    using NH4CookbookHelpers;
    using NHibernate;
    
    namespace MappingRecipes.ComponentCollections
    {
    
            public class Recipe : HbmMappingRecipe
        {
    
            protected override void AddInitialData(ISession session)
            {
    
              session.Save(new Customer
              {
    
                Name = "Max Weinberg",
                 Addresses =
                {
    
                    new Address
                    {
    
                      AddressLine1 = "E Street 1", 
                      City = "Belmar, NJ"
                     },
                    new Address
                    {
                    AddressLine1 = "Home street",
                    City = "Newark, NJ"
                    }
                },
                Tags = { "Drummer", "Bruce" }
              });
            }
        }
    }
  6. Run the application and start the ComponentCollections recipe. The query log will look similar to this:
    How to do it…

How it works…

Mapping a collection of simple values or components is very similar to mapping a collection of entities. We can use the same type of collections - bags, lists, and sets - following the same rules regarding duplicates and ordering.

Since this kind of collection always is implicitly one-to-many, we cannot specify that in the mapping. Instead, we use composite-element for components, specifying the included component properties, or element for simple values. Both require that we specify a separate table where the values should be persisted.

Similar to how it is with the entity collections, a set mapping requires working overrides of Equals and GetHashCode to function properly. Simple value types, such as string, provide this by default. Components, such as Address, require a unique implementation.

There's more…

The component collections mapped using composite-element may look similar to component properties and they are; however, there are a few differences.

A component in a composite-element mapping can contain other nested components that should be specified using a nested-composite-element tag. However, unlike component properties, they cannot contain collections. The reason for this is simply that all collection relationships require some kind of Id on the parent side and components don't provide this.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.255.86