Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to join table in fluent nhibernate

Tags:

how do we do this mapping but fluently?

<class name="Person" table="People">

    <id name="Id">
        <generator class="identity"/>
    </id>

    <property name="Name" />

    <join table="Addresses">
        <key column="PersonId"/>
        <property name="Line1"/>
        <property name="Line2"/>
        <property name="City"/>
        <property name="Country"/>
        <property name="ZipCode"/>
    </join>

</class>

I know i can use 'References' but i don't need all the columns from the related table. i just need one property.

like image 888
CurlyFro Avatar asked Aug 06 '09 19:08

CurlyFro


People also ask

What is the difference between NHibernate and fluent NHibernate?

Fluent NHibernate offers an alternative to NHibernate's standard XML mapping files. Rather than writing XML documents, you write mappings in strongly typed C# code. This allows for easy refactoring, improved readability and more concise code.


1 Answers

What Paco said is not right. This can be done in Fluent NHibernate. I searched the web myself quite a while, couldn't find anyone talking about this option, so I just played around with FNHibernate a little and finally managed to do it.

This was my scenario :

I have two tables -

"FormFields" => Columns { "FieldId", "FieldName", "FieldType", "DisplayOrder" }
"FormStructure" => Columns { "FormId", "FormType", "FieldId" }

These were my entities :

public class FormStructure
{
    public virtual Int32 FormId { get; private set; }
    public virtual Int32 FormType { get; set; }
    public virtual FormField FieldId { get; set; }
}

public class FormField
{
    public virtual int FieldId { get; private set; }
    public virtual String FieldName { get; set; }
    public virtual int? FieldType { get; set; }
    public virtual int? DisplayOrder { get; set; }
}

I have a couple of methods in my query that return a list of FormStructure objects. I wanted these methods to give me them ordered by the DisplayOrder field in the FormField object, and wanted the DisplayOrder available as a property in my FormStructure object for other reasons as well.

This basically means I needed to join the tables so that I would retrieve all the columns from the FormStructure table along with the DisplayOrder column from the FormField table, joining them on the matching FieldId columns.

What I did to solve this :

  1. I added a property called DisplayOrder to my FormStructure object.

    public virtual int? DisplayOrder { get; set; }
    
  2. I added the Join method to my FormStructure mapping class so it looked like this.

    public class FormStructureMap : ClassMap<FormStructure>
    {
        public FormStructureMap()
        {
            Table("FormStructure");
    
            Id(x => x.Id);
            Map(x => x.FormType);
            References(x => x.Schedule).Column("ScheduleId");
            References(x => x.Field).Column("FieldId");
            Map(x => x.IsMandatory).Nullable();
    
            Join("FormFields", m =>
            {
                m.Fetch.Join();
                m.KeyColumn("FieldId");
                m.Map(t => t.DisplayOrder).Nullable();
            });
        }
    }
    

The Join method will obviously join between the two tables on the column you defined in the KeyColumn method within the Join.

This will also remove some of the rows that have null values. In order to avoid this (I ran into this recently) you can add m.Optional(); inside the Join method.

I could now retrieve a list of FormStructure objects, order them by DisplayOrder and even have DisplayOrder available as a property in the FormStructure object.

return session.CreateCriteria<FormStructure>()
              .Add(Expression.Eq("FieldName", fieldName))
              .AddOrder(Order.Asc("DisplayOrder"))
              .List<FormStructure>();

This couldn't have been done before, because it wouldn't have recognized the DisplayOrder column in the Order clause I have there.

like image 180
gillyb Avatar answered Oct 21 '22 01:10

gillyb