2
votes

I have entity which has many data sources.

public class MyData
{
   public virtual int Id { get; set; }
   public virtual string Name { get; set; }
   public virtual IList<DataSource> Sources { get; set; }
   public MyData(){
       Sources = new List<DataSource>();
   }
}

and I have DataSource class which represents value object of MyData entity

public class DataSource
{
   public enum SourceEnum { dataOneSrc = 1, dataTwoSrc = 2}
   public virtual SourceEnum Source { get; set; }
   public virtual string InternalRefNr { get; set; }
}

I'm using nhibernate orm and its mapping by code approach. So I mapped value object using this link as ref. //http://lycog.com/programming/nhibernate-32-mapping-code-component-mapping/

public static Action<IComponentMapper<DataSource>> Mapping()
{
    return c =>{
                c.Property(p => p.Source);
                c.Property(p => p.InternalRefNr, m =>
                {
                    m.Length(255);
                });                    
            };
    }

and entity mapping using

public MyData()
{
    ...
    Bag<DataSource>(x => x.Sources,
        c => { },
        r =>{ r.OneToMany();}
    );
}

I'm getting Nhibernate.MappingException

{"Association references unmapped class: My.Model.DataSource"}

1
But is not this exception really clear? You just have to mapp the DataSource as well. That's it - Radim Köhler
I mapped DataSource above, public static Action<IComponentMapper<DataSource>> Mapping() - user1765862
can you please post as an answer how would you map entity, with list of value objects - user1765862
I provided some draft of the mapping and few essential links to Adam's Bar mapping by code. That should enlighten that matter a bit... - Radim Köhler
thanks for the effort, but I made design choice to make DataSource as an value object (not an entity). Do you have some advices on that manner? - user1765862

1 Answers

0
votes

COMPOSITE ELEMENT

If we do not want to map separated entity, we cannot use one-to-many. We need:

6.3. Collections of Values and Many-To-Many Associations (small cite)

For a collection of values, we use the tag.

<element
        column="column_name"                (1)
        type="typename"                     (2)
/>

...

A list of components (discussed in the next chapter):

<list name="CarComponents" table="car_components">
    <key column="car_id"/>
    <index column="posn"/>
    <composite-element class="Eg.Car.CarComponent">
            <property name="Price" type="float"/>
            <property name="Type" type="Eg.Car.ComponentType, Eg"/>
            <property name="SerialNumber" column="serial_no" type="String"/>
    </composite-element>
</list>

So in our case, we cannot use one-to-many but Component:

// instead of this
r =>{ r.OneToMany();}
// we need this for IList<string>
r.Element(e => { });
// this for DataSource as in the above question
r.Component(c => { });

ONE-TO-MANY:

The mapping by code should go like this: Hibernate's Mapping by Code. Any entity should have surrogate key (Id). That should be the DataSource:

public class DataSource
{
   public virtual int Id { get; set; }
   public virtual string InternalRefNr { get; set; }
   public virtual MyDataMyData{ get; set; }
}

The mapping of that class then could be:

public class DataSourceMap : DataSourceMapping<DataSource>
{
    public DataSourceMap()
    {
        Id(x => x.Id, m => m.Generator(Generators.Identity));
        Property(x => x.InternalRefNr);
        ManyToOne(x => x.MyData);
    }
}

And now we can map MyData based on Mapping-by-Code - Set and Bag

public MyData()
{
    ...
    Bag<DataSource>(x => x.Sources,
        c => { c.Inverse(true); },
        r =>{ r.OneToMany();}
    );
}