Search code examples
c#asp.net-mvcnhibernatefluent-nhibernatefluent-nhibernate-mapping

FluentNhibernate mapping and struct


I tought that it's simple problem, just few minuts in gogle and I got the solution etc. But, actually, I found nothing special.

So I got a struct(or class whatever) and a class where every field got such struct type. And I want to make/use table in my database using model, where each field got such type as struct.

As example struct is here

public class myStruct
{
    public float value;
    public string description;
}

and here the model which I want to use

public class FieldSummaryRow
{
    public int Id{ get; set } 
    public myStruct A { get; set; }
    public myStruct B { get; set; }
    public myStruct C { get; set; }
    public class FieldSummaryMap: ClassMap<FieldSummaryRow>
    {
      public FieldSummaryMap()
      {
        Id(x => x.Id);
        Map (x=>x.A);
        Map (x=>x.B);
        Map (x=>x.C);
      }
    }
}

But as I assume it just wouldn't work like that because of myStruct is not mapped correctly. So how should I solve this problem? Or do I nned map myStruct the same way before?


Solution

  • From NHibernate perspective, we should think about your struct as a <component>. It means, that there must be columns valueA and descriptionA for myStruct A, the same for B and C.

    See the documentation:

    Such a <component> myStruct would be at the end mapped like this xml snippet:

    <class name="FieldSummaryRow" table="...>
        ....
    
        <component class="myStruct" name="A">
          <property name="value"       column="valueA"       access="field" />
          <property name="description" column="descriptionA" access="field" />
        </component>
    
        <component class="myStruct" name="B">
        ...
    
    </class>
    

    As we can see here (article by Adam Bar - see the second half as a great summary of Fluent mapping)

    we would need this:

    public class FieldSummaryMap: ClassMap<FieldSummaryRow>
    {
        public FieldSummaryMap()
        {
            Id(x => x.Id);
            Component(x => x.A, c =>
            {        
                c.Map(x => x.value).Column("valueA").Access.CamelCaseField();
                c.Map(x => x.description).Column("descriptionA").Access.CamelCaseField();
            }
            Component(x => x.B, c =>
            ...
        }
    }