In my last post I went over the basics of mapping properties on a POCO object to fields on a database table. If you haven’t already check it out here. In this post I’m going to focus on mapping relationships, that is, what if we wanted our objects to contain concrete references to the objects with which they have relationships, rather than just foreign key properties.
One To One Relationships
Take a look at the way we set up the File object in the previous post,
{
public virtual int FileId { get; set; }
public virtual string FileName { get; set; }
public virtual Int64 FileSize { get; set; }
public virtual DateTime LastModified { get; set; }
public virtual int FolderId { get; set; }
}
Take a look at the property FolderId, what we’re want to achieve here to remove this property and replace it with a concrete reference to the object with which FolderId relates. That is, a Folder object. The first thing we need to do is replace the property with a Folder object property named Folder. So our File object will now look like,
{
public virtual int FileId { get; set; }
public virtual string FileName { get; set; }
public virtual Int64 FileSize { get; set; }
public virtual DateTime LastModified { get; set; }
public virtual Folder Folder { get; set; }
}
The next thing we need to do is update our FileMap object. You’ll remember from the previous post that the FileMap object is where we map our properties to our database fields.
We’re going to replace our FolderId property mapping with a different sort of mapping so that we get back a folder object rather than the FolderId value we were getting before, lets have a look at how it should look before continuing,
{
public FileMap()
{
Table("File");
Id(x => x.FileId, "FileId").GeneratedBy.Identity();
Map(x => x.FileName, "FileName");
Map(x => x.FileSize, "FileSize");
Map(x => x.LastModified, "LastModified");
References<Folder>(x => x.Folder, "FolderId");
}
}
What we’ve done here is we’ve taken out the line that maps FolderId to FolderId and updated it with a References mapping. This is just saying that the Folder property on the File object is now actually a concrete reference of the type Folder based on the foreign key FolderId, so when a File object is to be retrieved, also retrieve the Folder object for which it is related. That’s all there is to it, we now have a one to one relationship and any time we have a File object in scope, we can easily access the Folder object that the File belongs to. Ie.
We should do the same thing to our Folder object and our FolderMap object to map the ParentId field to a concrete Folder object also in the same manner as we achieved it on the File object.
{
public virtual int FolderId { get; set; }
public virtual string FolderLabel { get; set; }
public virtual Folder ParentFolder { get; set; }
}
{
public FolderMap()
{
Table("Folder");
Id(x => x.FolderId, "FolderId").GeneratedBy.Identity();
Map(x => x.FolderLabel, "FolderLabel");
References<Folder>(x => x.ParentFolder, "ParentId");
}
}
One To Many Relationships
Let’s consider the Folder object for a minute, what other relationships could we add to the Folder object to make in more complete. A Folder object obviously contains Files and Sub Folders, and these are a good example of one to many relationships, so let’s go ahead and implement a collection of File objects and a collection of Folder objects on our Folder object implementation.
{
public virtual int FolderId { get; set; }
public virtual string FolderLabel { get; set; }
public virtual Folder ParentFolder { get; set; }
public virtual IList<File> Files { get; set; }
public virtual IList<Folder> SubFolders { get; set; }
}
In our FolderMap object, we define a One to Many relationship slightly different to the way we defined our One to One relationships, we need to first call the HasMany<T>() method and pass into it the collection for which we are mapping the relationship (Files or SubFolders). Secondly, we need to call KeyColumn to tell nHibernate which column on the referenced objects defines the foreign key relationship to our root Folder object.
{
public FolderMap()
{
Table("Folder");
Id(x => x.FolderId, "FolderId").GeneratedBy.Identity();
Map(x => x.FolderLabel, "FolderLabel");
References<Folder>(x => x.ParentFolder, "ParentId");
HasMany<File>(x => x.Files).KeyColumn("FolderId");
HasMany<Folder>(x => x.SubFolders).KeyColumn("ParentId")
}
}
On the second last line in our FolderMap object above, we are telling nHibernate that the Files collection on our Folder object is a mapping to the foreign key field, FolderId, that is, when retrieving a Folder object, bring back with it all the File objects that reference its FolderId. And exactly the same for the last line, except we’re telling it to bring back all the Folder objects that reference the FolderId as their ParentId.
Now that we have a reference to all the Sub Folders and Files that exist under a Folder object, we can now access them whenever we have a Folder object in scope. Ie.
var aFolders = folder.SubFolders.Where(sf => sf.FolderLabel.StartsWith("A"));
That’s all there is to mapping relationships in nHibernate. One relationship type I didn’t mention is the Many to Many relationship, for which we need a link table. I’ll cover that in a later post.
Buy:Nymphomax.Amoxicillin.Acomplia.Prozac.Ventolin.Seroquel.Female Pink Viagra.Zetia.Female Cialis.Wellbutrin SR.Buspar.Advair.Zocor.Aricept.Lipothin.Benicar.Lasix.Cozaar.SleepWell.Lipitor….