Noob question.
I have this situation where I have these objects:
class Address
{
string Street;
string City;
...
}
class User
{
string UserID;
Address BillingAddress;
Address MailingAddress;
...
}
What is the proper way of storing this data using (fluent) nHibernate? I could use a separate Address table and create a reference, but they are 1:1 relationships so I don’t really want to incur the overhead of a join. Ideally I would store this as a single flat record.
So, my question is, what is the proper way of storing an instance of class ‘User’ in such a way that it stores its contents and also the two addresses as a single record? My knowledge is failing me on how I can store this information in such a way that the two Address records get different column names (e.g. BillingAddress_Street and MailingAddress_Street, for example), and also how to read a record back into a User instance.
These kinds of structures are referred to as a
component. They’re a normalized structure, and perfectly acceptable mechanism for representing data.In Fluent NHibernate there are a couple of ways to map components. Firstly there’s inline mappings, and then the external ComponentMap. I would recommend the latter in your situation, and in any scenario where you have a component that appears multiple times (either in the same entity, or across your domain).
Inline Components
To map a component, the simplest way is to use the
Componentmethod and specify how the component is composed using the body lambda.That’s your address mapped. You’ll need to repeat this for both addresses.
ComponentMap
The inline definition works fine for one-off components, but it can quickly become tiresome when you have multiple instances of the same component.
ComponentMapsolves this by extracting your component out into a self-contained, reusable, definition. You just use it exactly the same way as you doClassMap.Then in your
ClassMap, you just need to use the bodylessComponentmethod; this instructs Fluent NHibernate to search for aComponentMapmatching the type of the property (if one isn’t found, you’ll know about it).With the
ComponentMap, column prefixes are automatically created as necessary based on the property that contains the component. If you need to customise this there’s theColumnPrefixmethod that’s chained off the bodylessComponentcall.