Introduction
This article explains and illustrates on a practical example, how the support of different association mapping is implemented in Entity Developer with Fluent NHibernate.
This article also contains samples of mapping for the following associations:
NHibernate provides several ways for collection mappings:
- Set
- Bag
- List
- Map(Dictionary)
- Array
Within the database, a one-to-many mapping is arranged as a table with a primary key for the one side of the mapping and another table that contains a field, which references the primary key of the first table.
There can be a collection of items with no key that would allow retrieving them from the collection. In the collection, all elements can be defined as unique (a Set) or, alternatively, they can be duplicated (a Bag).
It is also possible to arrange a collection of items with a key that allows retrieving those items from the collection. This key can be either an integer (a List) or another simple type, or even an object (in this case, it is called a Dictionary).
Set and Map Types of Collection Mapping Sample
The database contains the Dept
and Emp
tables, which have a foreign key constraint between them.
The field DEPTNO
in the table Emp
receives the id value of the associated record in the Dept
table.

We perform the following sequence of operations: create an NHibernate model, add the Dept
and Emp
tables to the model, add the additional Fluent NHibernate template to generate fluent mapping. In the result, we have the following model:

If the navigation property Emps
is defined as Set, then the generated fluent mapping for the model will be as follows:
public class EmpMap : ClassMap<Emp>
{
public EmpMap()
{
Schema("dbo");
Table("Emp");
LazyLoad();
Id(x => x.EMPNO)
.Column("EMPNO")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Assigned();
Map(x => x.ENAME)
.Column("ENAME")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Length(10);
Map(x => x.JOB)
.Column("JOB")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Length(9);
Map(x => x.MGR)
.Column("MGR")
.CustomType("Int32")
.Access.Property()
.Generated.Never()
.CustomSqlType("int")
.Precision(10);
Map(x => x.HIREDATE)
.Column("HIREDATE")
.CustomType("DateTime")
.Access.Property()
.Generated.Never()
.CustomSqlType("datetime");
Map(x => x.SAL)
.Column("SAL")
.CustomType("Double")
.Access.Property()
.Generated.Never()
.CustomSqlType("float")
.Precision(53);
Map(x => x.COMM)
.Column("COMM")
.CustomType("Double")
.Access.Property()
.Generated.Never()
.CustomSqlType("float")
.Precision(53);
References(x => x.Dept)
.Class<Dept>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.Columns("DEPTNO");
}
}
public class DeptMap : ClassMap<Dept>
{
public DeptMap()
{
Schema("dbo");
Table("Dept");
LazyLoad();
Id(x => x.DEPTNO)
.Column("DEPTNO")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Assigned();
Map(x => x.DNAME)
.Column("DNAME")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Length(14);
Map(x => x.LOC)
.Column("LOC")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Length(13);
HasMany<Emp>(x => x.Emps)
.Access.Property()
.AsSet() .Cascade.None()
.LazyLoad()
.Inverse()
.KeyColumns.Add("DEPTNO", mapping => mapping.Name("DEPTNO")
.SqlType("int")
.Nullable());
}
}
The code above represents the generated model mapping classes. The mapping of each class contains the descriptions of the identity key mapping and class properties, as well as the definitions of the name of the table in the database, the name of the schema, to which the table belongs. In the mapping of the Emp
class, the References
function is used to create a reference to the master entity Dept
. In database terms, this is a many-to-one relationship; while the Columns
function specifies the name of the details table (Emp
) column, against which the foreign key is created in the database together with the master table(Dept
). In the mapping of the Dept
class, the HasMany
function is used to map a collection of entities as a one-to-many association, the call of AsSet()
indicates that the collection is mapped as a Set
; while the KeyColumns.Add
function specifies the name of the details table(Emp
) column, against which the foreign key is created in the database together with the master table(Dept
), its type and other mapping parameters.
On the other hand, if the collection type of the navigation property is set to Bag, than the generated fluent mapping for this model will be the same as shown above, except that when the HasMany
function is used to map the collection of entities as a one-to-many, the AsBag()
function will be called instead of the AsSet()
function to indicate that the collection is mapped as a Bag. All the other aspects of the mapping will be identical.
Map(Dictionary) type of collection mapping sample
In this example, we shall use the tables from the previous example for Set
and Bag
collection mapping.
The model is created in the same way as in the previous example. After the model has been created, we need to display the Association Editor dialog. Through this dialog box, we need to set the Generate relation property of the Dept navigation property to False
, since only Set
or Bag
may be used for the “many” end of a bidirectional association. After that, we need to set the collection type of the Emps
navigation property to Map
and specify the ENAME
column as the Index
column. Now the Employees
navigation property of the class Dept
is mapped as Map
collection mapping and is filled with instances of the class Emp
. You can find the instances by looking in the mapped table for Emp
and find records with the field DEPTNO
having value equal to DEPTNO
field value of the table Dept. The field ENAME
in the table Emp
receives the key value of the entry in the dictionary. The key used in the map is of type String
and can be found in the column ENAME
of the table used to store the Emp
objects. The type of the key used in this sample is string
.
Below is the generated fluent mapping for this model:
public class DeptMap : ClassMap<Dept>
{
public DeptMap()
{
Schema("dbo");
Table("Dept");
LazyLoad();
Id(x => x.DEPTNO)
.Column("DEPTNO")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Assigned();
Map(x => x.DNAME)
.Column("DNAME")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Length(14);
Map(x => x.LOC)
.Column("LOC")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Length(13);
HasMany<Emp>(x => x.Emps)
.Access.Property()
.AsMap<string>("ENAME")
.Cascade.None()
.LazyLoad()
.KeyColumns.Add("DEPTNO", mapping => mapping.Name("DEPTNO")
.SqlType("int")
.Nullable());
}
}
public class EmpMap : ClassMap<Emp>
{
public EmpMap()
{
Schema("dbo");
Table("Emp");
LazyLoad();
Id(x => x.EMPNO)
.Column("EMPNO")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Assigned();
Map(x => x.ENAME)
.Column("ENAME")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Length(10);
Map(x => x.JOB)
.Column("JOB")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Length(9);
Map(x => x.MGR)
.Column("MGR")
.CustomType("Int32")
.Access.Property()
.Generated.Never()
.CustomSqlType("int")
.Precision(10);
Map(x => x.HIREDATE)
.Column("HIREDATE")
.CustomType("DateTime")
.Access.Property()
.Generated.Never()
.CustomSqlType("datetime");
Map(x => x.SAL)
.Column("SAL")
.CustomType("Double")
.Access.Property()
.Generated.Never()
.CustomSqlType("float")
.Precision(53);
Map(x => x.COMM)
.Column("COMM")
.CustomType("Double")
.Access.Property()
.Generated.Never()
.CustomSqlType("float")
.Precision(53);
}
}
The code above represents the generated model mapping classes. The mapping of each class contains the descriptions of the identity key mapping and class properties, as well as the definitions of the name of the table in the database, the name of the schema, to which the table belongs. In the mapping of the Dept
class, the HasMany
function is used to map a collection of entities as a one-to-many, the call of AsMap<string>("ENAME")
indicates that the collection is mapped as Map
and specifies the key type and the name of the column that receives the key value of the entry in the dictionary; while the KeyColumns.Add
function specifies the name of the details table(Emp
) column, against which the foreign key is created in the database together with the master table(Dep
t
), as well as its type and other mapping parameters.
List and Array types of collection mapping sample
The database contains the Message
and Conversation
tables, linked though the foreign key constraint.
The field ConversationId
in the Message
table receives the id value of the associated record in the Conversation
table. Additionally, the Message
table has the Order
column, whose value determines the sequence of the message in the message list of each conversation.

We perform the following sequence of operations: create an NHibernate model, add the Message
and Conversation
tables to the model; display the Association Editor dialog, through which we set the Generation relation property of the Conversation
property to False
, since only Set
or Bag
may be used for the “many” end of a bidirectional association. After that, we set the collection type of the Messages navigation property to List
or Array
, specify the Order
column as the Index
column, add the additional Fluent NHibernate template to generate fluent mapping. In the result, we have the following model:

If the collection type of the Emps
navigation property is set to List, then the generated fluent mapping for this model will be as follows:
public class ConversationMap : ClassMap<Conversation>
{
public ConversationMap()
{
Schema("NHListSample");
Table("Conversation");
LazyLoad();
Id(x => x.Id)
.Column("Id")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Assigned();
Map(x => x.Description)
.Column("Description")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("varchar")
.Length(255);
Map(x => x.Date)
.Column("DATE")
.CustomType("DateTime")
.Access.Property()
.Generated.Never()
.Default("getdate()")
.CustomSqlType("datetime")
.Not.Nullable();
HasMany<Message>(x => x.Messages)
.Access.Property()
.AsList(index => index.Column("`Order`").Type<int>())
.Cascade.None()
.LazyLoad() .KeyColumns.Add("ConversationId", mapping => mapping.Name("ConversationId")
.SqlType("int")
.Not.Nullable());
}
}
public class MessageMap : ClassMap<Message>
{
public MessageMap()
{
Schema("NHListSample");
Table("Message");
LazyLoad();
Id(x => x.Id)
.Column("Id")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Identity();
Map(x => x.Order)
.Column("`Order`")
.CustomType("Int32")
.Access.Property()
.Generated.Never()
.Default("'0'")
.CustomSqlType("int")
.Not.Nullable()
.Precision(10);
Map(x => x.Text)
.Column("Text")
.CustomType("String")
.Access.Property()
.Generated.Never()
.Default("''")
.CustomSqlType("varchar")
.Not.Nullable()
.Length(45);
}
}
The code above represents the generated model mapping classes. The mapping of each class contains the descriptions of the identity key mapping and class properties, as well as the definitions of the name of the table in the database, the name of the schema, to which the table belongs. In the mapping of the Conversation
class, the HasMany
function is used to map a collection of entities as a one-to-many association, and the call of AsList()
indicates that the collection is mapped as List
; here we also specify mapping for the index; while the KeyColumns.Add
function specifies the name of the details table(Message
) column, against which the foreign key is created in the database together with the master table(Conversation
), its type and other mapping parameters. The index (and thus position) of the element in the list is specified by the value in the Order
field of the table.
Alternatively, if the collection type of the Emps
navigation property is set to Array, then the genrated fluent mapping for this model will be the same as above, however, in the mapping of the Conversation
class, when the HasMany
function is used to map a collection of entities as a one-to-many association, instead of calling AsList(index => index.Column("`Order`").Type<int>())
we have to call AsArray<int>(child => child.Id, map => map.Column("`Order`").Type<int>())
that sets the Array collection mapping. It should also be noted that we cannot call LazyLoad()
for Array collection mapping, so we need to remove this call.
Many-to-many associations use an intermediate table that has a foreign key to the tables of both associated entities. An object uses several objects of another type, and this latter object references several objects of the first type. As is always the case for many-to-many mappings in relational databases, we need a third table which provides the cross-references for the many-to-many relationship.
The database contains the Employees
, Territories
tables and EmployeeTerritories
table, which provides the cross-references for the many-to-many relationship.

We perform the following sequence of operations: create an NHibernate model, add the Employees
, Territories
, and EmployeeTerritories
tables, add the additional Fluent NHibernate template to generate fluent mapping. In the result, we have the following model:

The Territories navigation property of the type Employees
is a many-to-many property to a Set collection of objects with the type Territory
. The values for the objects in this collection can be found by looking for entries in the table for Territory
objects with an TerritoryID
equal to the values in the column TerritoryID
of the EmployeeTerritories
table with a value of EmployeeID
equal to this object's EmployeeID
.
The Employees
navigation property of the type Territory
is a many-to-many property to a Set
collection of objects with the type Employees
. The values for the objects in this collection can be found by looking for entries in the table for Employees
objects with an EmployeeID
equal to the values in the column EmployeeID
of the EmployeeTerritories
table with a value of TerritoryID
equal to this object's TerritoryID
.
In our example, both navigation properties are mapped as a Set
, although for many-to-many associations, we can use any other type of collection mapping, if needed.
Below is the generated fluent mapping for this model:
public class TerritoryMap : ClassMap<Territory>
{
public TerritoryMap()
{
Schema("dbo");
Table("Territories");
LazyLoad();
Id(x => x.TerritoryID)
.Column("TerritoryID")
.CustomType("String")
.Access.Property()
.CustomSqlType("nvarchar")
.Not.Nullable()
.Length(20)
.GeneratedBy.Assigned();
Map(x => x.TerritoryDescription)
.Column("TerritoryDescription")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nchar")
.Not.Nullable()
.Length(50);
Map(x => x.RegionID)
.Column("RegionID")
.CustomType("Int32")
.Access.Property()
.Generated.Never()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10);
HasManyToMany<Employees>(x => x.Employees)
.Access.Property()
.AsSet()
.Cascade.None()
.LazyLoad()
.Inverse()
.Schema("dbo")
.Table("EmployeeTerritories")
.FetchType.Join()
.ChildKeyColumns.Add("EmployeeID", mapping => mapping.Name("EmployeeID")
.SqlType("int")
.Not.Nullable())
.ParentKeyColumns.Add("TerritoryID", mapping => mapping.Name("TerritoryID")
.SqlType("nvarchar")
.Not.Nullable()
.Length(20));
}
}
public class EmployeesMap : ClassMap<Employees>
{
public EmployeesMap()
{
Schema("dbo");
Table("Employees");
LazyLoad();
Id(x => x.EmployeeID)
.Column("EmployeeID")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Identity();
Map(x => x.LastName)
.Column("LastName")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Not.Nullable()
.Length(20);
Map(x => x.FirstName)
.Column("FirstName")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Not.Nullable()
.Length(10);
Map(x => x.Title)
.Column("Title")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(30);
Map(x => x.TitleOfCourtesy)
.Column("TitleOfCourtesy")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(25);
Map(x => x.BirthDate)
.Column("BirthDate")
.CustomType("DateTime")
.Access.Property()
.Generated.Never()
.CustomSqlType("datetime");
Map(x => x.HireDate)
.Column("HireDate")
.CustomType("DateTime")
.Access.Property()
.Generated.Never()
.CustomSqlType("datetime");
Map(x => x.Address)
.Column("Address")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(60);
Map(x => x.City)
.Column("City")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(15);
Map(x => x.Region)
.Column("Region")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(15);
Map(x => x.PostalCode)
.Column("PostalCode")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(10);
Map(x => x.Country)
.Column("Country")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(15);
Map(x => x.HomePhone)
.Column("HomePhone")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(24);
Map(x => x.Extension)
.Column("Extension")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(4);
Map(x => x.Photo)
.Column("Photo")
.CustomType("BinaryBlob")
.Access.Property()
.Generated.Never()
.CustomSqlType("image")
.Length(2147483647);
Map(x => x.Notes)
.Column("Notes")
.CustomType("StringClob")
.Access.Property()
.Generated.Never()
.CustomSqlType("ntext")
.Length(1073741823);
Map(x => x.ReportsTo)
.Column("ReportsTo")
.CustomType("Int32")
.Access.Property()
.Generated.Never()
.CustomSqlType("int")
.Precision(10);
Map(x => x.PhotoPath)
.Column("PhotoPath")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(255);
HasManyToMany<Territory>(x => x.Territories)
.Access.Property()
.AsSet()
.Cascade.None()
.LazyLoad()
.Schema("dbo")
.Table("EmployeeTerritories")
.FetchType.Join()
.ChildKeyColumns.Add("TerritoryID", mapping => mapping.Name("TerritoryID")
.SqlType("nvarchar")
.Not.Nullable()
.Length(20))
.ParentKeyColumns.Add("EmployeeID", mapping => mapping.Name("EmployeeID")
.SqlType("int")
.Not.Nullable());
}
}
The code above represents the generated model mapping classes. The mapping of each class contains the descriptions of the identity key mapping and class properties, as well as the definitions of the name of the table in the database, the name of the schema, to which the table belongs. Additionally, in the mapping of the classes, the HasManyToMany
function is used to set up the mapping for the navigation property of the many-to-many association: we need to specify the type of collection mapping, the name of the link table in the database, which provides the cross-references for the many-to-many relationship, the name of the schema, to which the table belongs; we also need to specify the mapping for columns of the (EmployeeTerritories
) link table, which will provide cross-references for the many-to-many relationship between the associated tables (Employees
and Territories
).
One-to-one associations are the simplest kind of associations. They usually correspond to the foreign key relations when the foreign key column is the primary key column.
The following two cases are possible, when we map a one-to-one association:
Case 1. When the foreign key and the primary key in the dependent entity class (class, corresponding to the table that has the foreign key) consist of the same columns.
The database contains the Person
and Contact
tables, between which there is a foreign key created against the primary key fields of these tables.
We perform the following sequence of operations: create an NHibernate model, add the Person
and Contact
tables to the model, add the additional Fluent NHibernate template to generate fluent mapping. In the result, we have the following model:
Below is the generated fluent mapping for this model:
public class ContactMap : ClassMap<Contact>
{
public ContactMap()
{
Schema("dbo");
Table("Contact");
LazyLoad();
Id(x => x.ContactID)
.Column("ContactID")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Assigned();
Map(x => x.FirstName)
.Column("FirstName")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Not.Nullable()
.Length(50);
Map(x => x.LastName)
.Column("LastName")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Not.Nullable()
.Length(50);
Map(x => x.Email)
.Column("Email")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(50);
Map(x => x.Phone)
.Column("Phone")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nchar")
.Length(13);
HasOne(x => x.Person)
.Class<Person>()
.Access.Property()
.Cascade.None()
.LazyLoad();
}
}
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Schema("dbo");
Table("Person");
LazyLoad();
Id(x => x.PersonID)
.Column("PersonID")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Assigned();
Map(x => x.BirthDay)
.Column("BirthDay")
.CustomType("DateTime")
.Access.Property()
.Generated.Never()
.CustomSqlType("datetime")
.Not.Nullable();
Map(x => x.ADDRESS)
.Column("ADDRESS")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Not.Nullable()
.Length(200);
HasOne(x => x.Contact)
.Class<Contact>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.Constrained();
}
}
The code above represents the generated model mapping classes. The mapping of each class contains the descriptions of the identity key mapping and class properties, as well as the definitions of the name of the table in the database, the name of the schema, to which the table belongs. Additionally, in the mapping of the classes, the HasOne
function is used to set up the mapping of the navigation property of the one-to-one association: it specifies the class, which the navigation property refers to, its access and other mapping settings, while the call of the Constrained()
in this definition indicates that the (Person
) table, corresponding to this type, has the foreign key.
Case 2. When foreign key is some non-primary unique property. You need to specify the foreign key column of the constrained table in this case.
The database contains the Person
and Contact
tables, between which there is a foreign key that is created against the ContactID
primary key field of the Contact
table and the ContactID
unique field of the Person
table.
We perform the following sequence of operations: create an NHibernate model, add the Person
and Contact
tables to the model; display the Association Editor dialog and set the Separate Foreign Key parameter of the Contact
property to True
as well as set the Foreign Key column to the ContactID
column, and, finally, add the additional Fluent NHibernate template to generate fluent mapping. In the result, we have the following model:
Below is the generated fluent mapping for this model:
public class ContactMap : ClassMap<Contact>
{
public ContactMap()
{
Schema("OneToOneSeparateFK");
Table("Contact");
LazyLoad();
Id(x => x.ContactID)
.Column("ContactID")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Assigned();
Map(x => x.FirstName)
.Column("FirstName")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Not.Nullable()
.Length(50);
Map(x => x.LastName)
.Column("LastName")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Not.Nullable()
.Length(50);
Map(x => x.Email)
.Column("Email")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Length(50);
Map(x => x.Phone)
.Column("Phone")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nchar")
.Length(13);
HasOne(x => x.Person)
.Class<Person>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.PropertyRef(p => p.Contact);
}
}
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Schema("OneToOneSeparateFK");
Table("Person");
LazyLoad();
Id(x => x.PersonID)
.Column("PersonID")
.CustomType("Int32")
.Access.Property()
.CustomSqlType("int")
.Not.Nullable()
.Precision(10)
.GeneratedBy.Assigned();
Map(x => x.BirthDay)
.Column("BirthDay")
.CustomType("DateTime")
.Access.Property()
.Generated.Never()
.CustomSqlType("datetime")
.Not.Nullable();
Map(x => x.ADDRESS)
.Column("ADDRESS")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("nvarchar")
.Not.Nullable()
.Length(200);
References(x => x.Contact)
.Class<Contact>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.Columns("ContactID");
}
}
The code above represents the generated model mapping classes. The mapping of each class contains the descriptions of the identity key mapping and class properties, as well as the definitions of the name of the table in the database, the name of the schema, to which the table belongs. In the mapping of the Contact
class, the HasOne
function is used to set up mapping of the Person
navigation property of the one-to-one association: the function specifies the class the navigation property references, navigation property access, and other settings of the mapping. In the mapping of the Person
class, the References
function is used to set up the mapping of the Contact
navigation property of the one-to-one association: it specifies the class the navigation property references, specifies the ContactID
field of the Person
table, against which the foreign key with the Contact
table is created, navigation property access and other settings of the mapping.
To demonstrate how to implement and use associations along with many other kinds of NHibernate mapping, we release NHibernate Mapping Samples application, which demonstrates 50 different mapping cases, how they are mapped using both fluent and XML mapping, and their usage. Visit our NHibernate Mapping Samples blog article to read more about this application and download it.
Related Articles