Recently I found myself working in NHibernate with my first ever many-to-one and many-to-many relationships between entities. After spending a couple hours trying to sort this out, I agree with Steve Bohlen that the hardest part of NHibernate is properly mapping your domain objects.
Enter NHibernate Made Simple. This project helped me get me on the right path and away from the mapping mayhem I was previously experiencing. This application has a one-to-many relationship between Customer and Order, and amany-to-many relationship between Order and Products. I typically like to structure my NHibernate projects different (having mapping files in their own folder, for a start) but this provides a great understanding of the concept.
Let's take a look at our relevant domin objects and their properties:
private Address Address = new Address();
private int ID = -1;
private string Name = "[New Customer]";
private IList<Order> Orders = new List<Order>();
private Customer Customer = null;
private DateTime Date = DateTime.Today;
private int ID = -1;
private IList<Product> OrderItems = new List<Product>();
private int ID = -1;
private string Name = String.Empty;
The domain objects are straightforward enough. It's the mapping files where this gets a bit tricky on your first few times of doing this. Here are the mapping files for each object, omitting everything outside of the <class> tag:
<!-- Mappings for class 'Customer' -->
<class name="Customer" table="Customers" lazy="false">
<!-- Identity mapping -->
<id name="ID">
<column name="CustomerID" />
<generator class="native" />
</id>
<!-- Component mapping: Address-->
<component name="Address">
<property name="StreetAddress" />
<property name="City" />
<property name="State" />
<property name="Zip" />
</component>
<!-- One-to-many mapping: Orders -->
<bag name="Orders" cascade="all-delete-orphan" lazy="false">
<key column="CustomerID" />
<one-to-many class="Order" />
</bag>
<!-- Simple mappings -->
<property name="Name" />
</class>
<!-- Mappings for class 'Order' -->
<class name="Order" table="Orders" lazy="false">
<!-- Identity mapping -->
<id name="ID">
<column name="OrderID" />
<generator class="native" />
</id>
<!-- Many-to-one mapping: Customer -->
<many-to-one name="Customer"
class="Customer"
column="CustomerID"
cascade="all" />
<!-- Many-to-many mapping: OrderItems -->
<bag name="OrderItems" table="OrderItems" cascade="none" lazy="false">
<key column ="OrderID" />
<many-to-many class="Product" column="ProductID" />
</bag>
<!-- Simple mappings -->
<property name="Date" />
</class>
<!-- Mappings for class 'Product' -->
<class name="Product" table="Products" lazy="false">
<!-- Identity mapping -->
<id name="ID">
<column name="ProductID" />
<generator class="native" />
</id>
<!-- Simple mappings -->
<property name="Name" />
</class>
First make a note of the properties in each of the classes, then take a look at how the names of these properties fit in the mapping files. The above examples have comments to make clear where in the xml you need to look to see how the relationships are mapped. Follow this example when you start out and you will be able to get past any early hurdles you have creating mapping files.
Happy learning!