Question

I have Article and Image.

Image is value object and Article is entity. Image is mapped as component like

public class ImageMap 
    {
        public static Action<IComponentMapper<Image>> Mapping()
        {
            return c =>
                {
                    c.Property(p => p.AltText);
                    c.Property(p => p.Name, m => 
                    {
                        m.Length(255);
                    });
                    c.Property(p => p.Path, m =>
                    {
                        m.Length(255);
                    });
                    c.Property(p => p.Height);
                    c.Property(p => p.Width);
                    c.Parent(x => x.Article, p => p.Access(Accessor.ReadOnly));                    
                };
        }
    }

I dont know how to map list of components in nhibernate mapping by code approach On other components where is only one object instead of collection I would use this

ArticleMap

Component(c => c.Address, AddressMap.Mapping());

how to map collection of components (images) ?

Article.cs

public virtual IList<Image> Images {get; set;}
Was it helpful?

Solution

What we need is the 7.2. Collections of dependent objects. While the principle is almost the same as in case of 5.1.13. <component>, element name in this case is <composite-element>. Well in fact, it is a bit more confusing with mapping-by-code, where we need IComponentElementMapper<>

So, this would be our mapping method

public class ImageMap 
{
    // the <composite-element> as IComponentElement<>
    // will replace the above mapper

    // public static Action<IComponentMapper<Image>> Mapping()
    public static Action<IComponentElementMapper<Image>> Mapping()
    {
        return c =>
            {
                c.Property(p => p.AltText);
                c.Property(p => p.Name, m => 
                {
                    m.Length(255);
                });
                c.Property(p => p.Path, m =>
                {
                    m.Length(255);
                });
                c.Property(p => p.Height);
                c.Property(p => p.Width);
                c.Parent(x => x.Article, p => p.Access(Accessor.ReadOnly));                    
            };
    }
}

And now we will pass it, as Adam Bar documented here Mapping-by-Code - Set and Bag, into the mapping

// mapping for property:
// public virtual IList<Image> Images {get; set;}

Bag(x => x.Images // reference
       , b => { } // bag properties mapper
       , v => v.Component(ImageMap.Mapping()) // here we pass the <composite-element>
   ); 

And the xml result will be as expected:

<bag name="Images" ... >
  <key column="ArticleId" ... />
  <composite-element class="Occupation">
    <parent name="Article" access="readonly" />
    <property name="AltText" />
    <property name="Name" length="255" />
    ...
  </composite-element>
</bag>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top