20
Fluent NHibernate & HasOne(): how to implement a one-to-one relationship
17 Comments · Posted by Bruno França dos Reis in C#, DDD, NHibernate
For a (very) long time I’ve been googling, binging, stackoverflowing, [your-search-engine]ing for a simple yet complete example showing how to implement a one-to-one relationship using Fluent NHibernate.
Fluent NHibernate and lambda expressions as data
If you don’t already know, Fluent NHibernate is a fantastic open-source library to be used in conjunction with NHibernate, a powerful O/RM library for .NET. NHibernate works by reading a (usually) manually created XML file that represents the mapping between the Object Oriented and Relational models. There are obvious annoying problems related to the fact of using this XML file, such as not being refactoring-friendly.
Fluent NHibernate is based on the power and expressiviness of lambda expressions to allow for a concise, strongly-type, refactoring-friendly mappings, that eliminates the need of hand-crafted XML files.
It is a very nice example of a somewhat modern pattern, borrowed from functional programming, now possible in C#: using lambda expressions as data. For more details about such emerging patterns, I strongly recommend you this excelent article on MSDN Magazine.
The problem is that I’ve not yet found an example that fits my needs, and Fluent NHibernate’s documentation is somewhat scarce (a big drawback of Fluent NHibernate, I’d say, specially when using it inside a company). What you will most certainly find is people telling you that you might actually need a many-to-one relationship. No, I was needing a one-to-one relationship, I swear, and couldn’t find a single example on how to correctly implement it with NHibernate and Fluent NHibernate. Note that I have almost no experience with NHibernate without Fluent NHibernate. I’ve never created an XML mapping that was more complex than almost-trivial. Had I had some more experience with it, I might had been able to solve this problem more easily.
So I present here a scenario, similar to the one I was facing, involving a one-to-one relationship and how I managed to implement it with Fluent NHibernate.
The scenario
Let’s say you have a project that deals with Clients. You normally would have a class to represent this entity, such as:

public class Client {
protected virtual int Id { get; set; }
public virtual string Name { get; set; }
/* ... */
}
(note that the protected id and the virtual modifiers are there to please NHibernate; it creates a proxy class around your model class, so it needs to be able to override getters and setters)
Using Fluent NHibernate, you need no XML file to manage the mappings, all you need is this:
using FluentNHibernate.Mapping;
public class ClientMap : ClassMap<Client> {
Id(x => x.Id);
Map(x => x.Name);
/* ... */
}
And that’s it! Should you need to refactor Name and call it, say, FullName, the mapping would be automatically updated accordingly (given that you use any minimally-competent refactoring tool).
Here is the corresponding database (the names are slightly modified, not following the standard Fluent NHibernate convention):

Adding some relationships
With NHibernate you are free to model your domain in the object-oriented world, with all the kinds of relationships you might want, and it will take care of the database for you.
One such relationship is a many-to-one relationship. Let’s say you want to possibly classify your clients according to some Profiles. A client may have one profile, or no profile at all (if you have not yet decided what is his profile). You would have something like this:

public class Client {
/* ... */
public virtual Profile Profile { get; private set; }
/* ... */
}
public class Profile {
protected virtual int Id { get; set; }
public virtual string ProfileName { get; private set; }
/* ... */
}
The mappings would be:
public class ProfileMap : ClassMap<Profile> {
Id(x => x.Id);
Map(x => x.ProfileName);
/* ... */
}
public class ClientMap : ClassMap<Client> {
/* ... */
References(x => x.Profile);
/* ... */
}
And this is the database, as expected:

And that’s all. Should you want, Fluent NHibernate can automatically generate the database for you as well, with one extra line of code on the configuration of the connection to the database.
Simple, huh?
The problem – a one-to-one relationship
Now suppose you have your system running, in production. Everything is fine, not too many bugs (and the ones found not too scary), the business (that partly relies on your software) is running OK.
One day, your boss calls you and (as you can expect) tells you he needs a new feature. Let’s say he needs to gather some more details about clients, about their alimentary habits.
You, as the developer, decide that you shall not modify the whole Client class, adding many alimentary properties to it. You’d rather create a new class AlimentaryHabits. However this data is still part of the client, you just decide to separate the classes not to burden the client.
The same argument applies to the database: you want to create a separate table not to burden the Clients table. Should you want to have two classes but only one table, you can create your mappings using Component(), but I won’t discuss this here since it is already well documented elsewhere.
What we want in the database is two tables, a Clients with its primary key Id, and a AlimentaryHabits table, with a primary key ClientId that is also a foreign key, referring to Client‘s primary key:

What you would like to have is a model that looks like this:

public class Client {
/* ... */
public virtual AlimentaryHabits AlimentaryHabits
{ get; private set; }
/* ... */
}
public class AlimentaryHabits {
public virtual bool LikesPasta { get; set; }
public virtual bool LikesPizza { get; set; }
public virtual int AverageDailyCalories { get; set; }
}
This is what we would like to have. But it is not that easy. No. To please NHibernate and allow Fluent NHibernate to correctly create our mappings, we need to change things a bit. And this is my problem, I couldn’t find any example on how to implement this mapping.
The solution
To implement this model and the corresponding fluent mapping, we need to modify things a bit. This is the domain:

public class AlimentaryHabits {
private int ClientId { get; set; }
private Client Client { get; set; }
protected AlimentaryHabits() { }
public AlimentaryHabits(Client client) {
Client = client;
}
public virtual bool LikesPasta { get; set; }
public virtual bool LikesPizza { get; set; }
public virtual int AverageDailyCalories { get; set; }
}
We need two things to satisfy our OR/M solution:
- an id of the same type as the main class; and
- a reference to the main object;
This reference would represent a bidirectional relationship, although we wanted a unidirectional one (you could want something different for your domain). However we could make it private, and it is not even used inside the class, it’s just used by NHibernate. Also, note that now we have two constructors. The public constructor, taking a Client parameter, is the one you will use in your code whenever you want to assign a client some alimentary habits, such as: AlimentaryHabits = new AlimentaryHabits(this);. The protected constructor is used internally by NHibernate, and must be present. You can completely ignore it.
This is the corresponding mapping:
public class AlimentaryHabitsMap : ClassMap<AlimentaryHabits>
{
Id(Reveal.Property<AlimentaryHabits>("ClientId"))
.GeneratedBy.Foreign("Client");
HasOne(
Reveal.Property<AlimentaryHabits, Client>("Client"))
.Constrained()
.ForeignKey();
Map(x => x.LikesPasta);
Map(x => x.LikesPizza);
Map(x => x.AverageDailyCalories);
}
public class ClientMap : ClassMap<Client> {
/* ... */
HasOne(x => x.AlimentaryHabits)
.Cascade.All();
/* ... */
}
(the Reveal.Property thing is because both ClientId and Client properties are private, and thus not accessible from the mapping class; they will be accessed through reflection by NHibernate)
This model setup, along with this mapping, will create almost the model we initially wanted to, and the exact database representation we wanted!
Conclusion
This involved more effort than I initially thought it would, but now I have a neat solution. And the next time I will need this, it will be easy to implement, following this directions.
If you know a way to simplify this further, or if you like it, or if you have any questions, leave a comment, I’d be glad to further improve this article!
Good luck!
No tags

Sean · 2010/03/23 at 01:58
Thanks for this article, it was _really_ helpful in getting setup.
Just one problem though – I can’t delete the child object from the database (though I can create and update).
Any ideas?
Admin comment by Bruno · 2010/03/25 at 21:13
Hi Sean!
I’m glad to hear that it was useful!
About your problem, you cannot achieve what you are looking for. Here I deal with a one-to-one relationship (1-1), that is, for every Client, there is one and exactly one AlimentaryHabits. No more, no less. It is like a big object that is simply split on two smaller parts. You cannot think of a child object in this situation. If you want to delete something, you must delete both the Client and the associated AlimentaryHabits at once, because they compose a single unit.
From what you say, it seems that what you want to implement is a different kind of relationship: one to at most one (1 – 0..1). In this kind of relationship, not every Client will have an associated AlimentaryHabits. But in this case you cannot map with “HasOne”, simply because you are not sure that the Client will HaveOne AlimentaryHabits. For this situation, what best approximates your model is a Map relationship.
If you have any questions, post them here!
Good luck,
Bruno
Sean · 2010/03/31 at 00:16
Thanks for the reply Bruno, I managed to solve my problem by using a HasMany over a private collection and ensuring the 1-0..1 relationship in my domain.
I’ll look in to the Map relationship!
Cheers
Sean
Adam · 2010/04/01 at 18:13
Bruno,
I have a similar situation but it is more like the first conclusion you came to above. I have a class Family, I also have a class AuditFamily, which adds a few extra properties. A Family object can have zero or 1 AuditFamily objects (not all families participate in an audit). When I do the standard Family class has a single AuditFamily object and AuditFamily class has a single Family object I get the following DB structure(without the needless details):
Family table:
FamilyID
AuditFamilyID
…other…
AuditFamily table:
AuditFamilyID
…other…
This works, but the problem is that I want the AuditFamily table to hold the FamilyID, NOT the family table to hold the AuditFamilyID as I would rather not impact that base family table at all. I would think this is more a normalized model anyway, as it is a 0:1 relationship. In short, I have a core set of classes that I am “extending” with other properties. I’m pretty new to fluent and nhibernate so I apologize ahead of time if I’m missing something obvious. Thanks in advance!
Maksim · 2010/04/09 at 17:14
Hi, Bruno.
I use your solution, but I have some trouble. I can’t delete my entities. You wrote:”you must delete both the Client and the associated AlimentaryHabits at once”. How this do? Can you publish some example for deleting “Client” entity.
Thanks,
Maksim
Geert · 2010/06/14 at 11:07
Great and simple explanation!
Bookmarked
granadaCoder · 2010/12/16 at 18:04
First, this is GREATLY APPRECIATED.
I got my domain to map, ONLY because I found this article.
Deprecated-Code small tidbit:
This original code:
HasOne(
Reveal.Property(“Client”))
.Constrained()
.ForeignKey();
Reveal.Property seems to have been replaced with
Reveal.Member. Not a biggie, but maybe will help a new reader.
……..
THANKS for posting your solution.
I believe in prototyping every situation you might encounter, and this filled a big gap.
Jonn · 2011/01/03 at 12:50
Finally! I’m in the same boat as you are. I really do want a one-to-one relationship and your has been the most helpful explanation i’ve found instead of the constant redirection to the “I think you mean many-to-one” article! Thanks
Lee · 2011/01/11 at 17:35
Based on your example. When i say:
var client = new Client() { … };
client.AlimentaryHabits = new AlimentaryHabits(client) { … };
session.Save(client);
I receive the error:
NHibernate.Id.IdentifierGenerationException: null id generated for: AlimentaryHabits
I’d appreciate any suggestions i want i might have done wrong. Thanks
Meir · 2011/03/25 at 08:18
Great solution, but one concern.
I see bidirectional one-to-one relationship ClientAlimentaryHabits. Do not we need to specify inverse=true parameter on one side?
Mohammad · 2011/05/10 at 16:38
Great solution. You saved a lot of my time.
Thanks,
Mohammad
Glauber · 2011/05/21 at 15:39
Where
Id(Reveal.Property(“ClientId”))
.GeneratedBy.Foreign(“Client”);
HasOne(Reveal.Property(“Client”))
.Constrained()
.ForeignKey();
is Should not be
Id(x => Reveal.Property Reveal.Property<AlimentaryHabits, Client("Client"))
.Constrained()
.ForeignKey();
???
Glauber · 2011/05/21 at 15:41
HasOne( x => Reveal.Property(“Client”))
.Constrained()
.ForeignKey();
lacked space for this second part in previous post
ricky87 · 2011/05/24 at 15:22
thanks..
Artem · 2011/07/26 at 23:18
Thanks Bruno! I wonder how you figured out yourself how to achieve this thing
Great article and thanks for sharing!
Artem
Joy · 2011/09/21 at 07:39
public class Address
{
private String StudentId { get; set; }
private Student Student { get; set; }
public Address(Student student)
{ Student = student; }
}
public class Student
{
public virtual String Studentid { get; set; }
public virtual Address Address { get; set; }
}
public StudentMap()
{
Id(x => x.Studentid).GeneratedBy.Assigned();
HasOne(x => x.Address).Cascade.All();
}
public AddressMap()
{
Id(x=> Reveal.Member(“StudentId”))
.GeneratedBy.Foreign(“Student”);
HasOne( x=> Reveal.Member(“Student”))
.Constrained()
.ForeignKey();
}
its giving error :
“Could not determine type for: System.Linq.Expressions.Expression`1[[System.Func`2[[CastleTest.Domain.Address, CastleTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, for columns: NHibernate.Mapping.Column(Member)”
can you please tel whats the problem actually why inspite of having one to one mapping as you told its still not working out :(
Oliver · 2012/01/23 at 15:18
Interesting article! I don’t see the point of having a private Client in AlimentaryHabits though. Why don’t you declare it simply as protected?