Search code examples
c#-4.0nhibernatefluent-nhibernatefluent

Fluent Hibernate One-To-One mapping issue


I am not sure how to map below given entities.

Below are the tables.

Employee { ID, Name, Role_ID } (Role_ID is foreign key from Role table)
Role     {Role_ID, Name }    

Below are the classes:

class Employee
{
     public virtual string ID { get; set; }
     public virtual string Name { get; set; }
     public virtual Role EmpRole { get; set; }
}

class Role
{
     public virtual string RoleID { get; set; }
     public virtual string Name { get; set; }
}

Below are the Mappings:

  public class EmployeeMap : ClassMap<Employee>
  {
    public EmployeeMap()
    {
        Table("Employee");
        Id(x => x.ID, "ID");
        Map(x => x.Name, "NAME");
        //for relationship not sure which mapping to be used???  

    }
  }

  public class RoleMap : ClassMap<Role>
  {
    public RoleMap()
    {
        Table("Role");
        Id(x => x.RoleID, "ROLE_ID");
        Map(x => x.RoleID, "ROLE_ID");
        Map(x => x.Name, "ROLE_NAME");
        //For relationship not sure what to be used???? 
    }
  }

Scenario : One Employee will have one role. One Role can be assigned to multiple employee.

Please suggest me how to write the relationship for both entities?


Solution

  • You are facing the most common scenario. The mapping in this case would be many-to-one which in fluent is represented with .References()

    public EmployeeMap()
    {
        Table("Employee");
        Id(x => x.ID, "ID");
        Map(x => x.Name, "NAME");
        References(x => x.EmpRole , "Role_ID");
    }
    

    The best overview (I am aware about) is available here:

    Mapping-by-Code - ManyToOne by Adam Bar

    Suprisingly this post is not about fluent NHibernate but about mapping by code. The second half however, compares with fluent - and provides really comprehensive overivew. Small snippet:

    References(x => x.PropertyName, "column_name")
        .Class<ClassName>()
        .Cascade.SaveUpdate()
        .Fetch.Join()
        .Update()
        .Insert()
        .ReadOnly()
        .Access.Field()
        .Unique()
        .OptimisticLock()
        .LazyLoad(Laziness.Proxy)
        .PropertyRef(x => x.PropertyRef)
        .NotFound.Ignore()
        .ForeignKey("column_fk")
        .Formula("arbitrary SQL expression")
        .Index("column_idx")
        .Not.Nullable()
        .UniqueKey("column_uniq");
    

    In case you would search for NHibernate doc (fluent operates on top of it) you should check the:

    5.1.10. many-to-one

    If you want Fluent-NHibernate doc:

    Finally, if you like to see which Employees belong to each Role, you can extend your POCO:

    class Role
    {
         public virtual string RoleID { get; set; }
         public virtual string Name { get; set; }
         public virtual IList<Employee> Employees { get; set; }
    }
    

    And map it as a <bag>.

    HasMany(x => x.Employees)
       .KeyColumn("Role_ID")
       .Inverse()
       .BatchSize(25)
    

    See: