Mapping Relations with Fluent NHibernate
In this section I explain how you can implement mappings using Fluent NHibernate.
One-to-One Mapping
Consider the following class, called Product.
public class Product
{
public virtual Int32 ProductID { get; set; }
public virtual String Description { get; set; }
public virtual String CreatedBy { get; set; }
public virtual DateTime CreatedDate { get; set; }
public virtual String ModifiedBy { get; set; }
public virtual DateTime ModifiedDate { get; set; }
public virtual Int32 ProductTypeId { get; set; }
public virtual String Model { get; set; }
}
To create a one-to-one mapping for the above class, you need to create a class that extends the generic ClassMap<T> class. Here is an example:
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
Table("Products");
Id(x => x.ProductID).GeneratedBy.Identity();
Map(x => x.Description);
Map(x => x.ModifiedBy);
Map(x => x.ModifiedDate);
Map(x => x.CreatedBy);
Map(x => x.CreatedDate);
Map(x => x.ProductTypeId);
Map(x => x.Model);
}
}
One-to-Many Mapping
Consider the following two classes, User and Roles:
public class User
{
virtual public int UserID { get; set; }
virtual public string UserName { get; set; }
virtual public string EmailAddress { get; set; }
virtual public string Password { get; set; }
virtual public Roles UserRoles {get; set;}
}
public class Roles
{
public Roles ()
{
UserList = new List<User>();
}
virtual public int RoleID { get; set; }
virtual public string RoleName { get; set; }
virtual public string RoleXML { get; set; }
public IList<User> UserList { get; protected set;}
}
With this one-to-many mapping between user and roles, one user can have multiple roles. Here are the mapping classes to implement this.
public class UserMap : ClassMap<User>
{
public UserMap()
{
Table("User");
Id(x => x.UserID).GeneratedBy.Identity();
Map(x => x.UserName);
Map(x => x.EmailAddress);
Map(x => x.Password);
References<Roles>(x => x.Roles);
}
}
The RolesMap class maps the user's roles as shown below:
public class RolesMap : ClassMap<Roles>
{
public RolesMap()
{
Table("Roles");
Id(x => x.RoleID).GeneratedBy.Increment();
Map(x => x.RoleName);
Map(x => x.RoleXML);
HasMany<User>(x => x.UserList)
.IsInverse()
.AsBag();
}
}
Many-to-Many Mapping
Using the User and Roles classes, the following example demonstrates how to implement many-to-many relationships.
public class User
{
virtual public int UserID { get; set; }
virtual public string UserName { get; set; }
virtual public string EmailAddress { get; set; }
virtual public string Password { get; set; }
public virtual IList<Roles> UserRoles { get; set; }
}
public class Roles
{
virtual public int RoleID { get; set; }
virtual public string RoleName { get; set; }
virtual public string RoleXML { get; set; }
public virtual IList<User> Users { get; set; }
}
Here is how the UserMap class would look.
public class UserMap : ClassMap<User>
{
public UserMap()
{
Table("User");
Id(x => x.UserID).GeneratedBy.Identity();
Map(x => x.UserName);
Map(x => x.EmailAddress);
Map(x => x.Password);
HasManyToMany<Roles>(x => x.UserRoles).Table("RolesUser")
.ParentKeyColumn("UserID") .ChildKeyColumn("RoleID");
}
}
The RolesMap class below implements a many-to-many relationship with Roles and User classes.
public class RolesMap : ClassMap<Roles>
{
public RolesMap()
{
Table("Roles");
Id(x => x.RoleID).GeneratedBy.Increment();
Map(x => x.RoleName);
Map(x => x.RoleXML);
HasManyToMany<User>(x => x.Users).Table("RolesUser") .ParentKeyColumn("RoleID") .ChildKeyColumn("UserID");
}
}
Notice the use of the HasManyToMany keyword while mapping the User and the Roles classes.
Summary
Fluent NHibernate offers a fluent API for mapping classes with NHibernate -- sans the need for XML files. In this article you saw how to use Fluent NHibernate to implement various types of mappings, such as one-to-one, one-to-many and many-to-many.