开发者

fluent nhibernate - storing and retrieving three classes in/from one table

开发者 https://www.devze.com 2022-12-30 18:41 出处:网络
Noob question. I have this situation where I have these objects: class Address { string Street; strin开发者_StackOverflow中文版g City;

Noob question.

I have this situation where I have these objects:

class Address
{      
   string Street;
   strin开发者_StackOverflow中文版g 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 Component method and specify how the component is composed using the body lambda.

  Component(x => x.BillingAddress, addr =>
  {
    addr.Map(x => x.Street);
    addr.Map(x => x.City);
  });

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. ComponentMap solves this by extracting your component out into a self-contained, reusable, definition. You just use it exactly the same way as you do ClassMap.

public class AddressMap : ComponentMap<Address>
{
  public AddressMap()
  {
    Map(x => x.Street);
    Map(x => x.City);
  }
}

Then in your ClassMap, you just need to use the bodyless Component method; this instructs Fluent NHibernate to search for a ComponentMap matching the type of the property (if one isn't found, you'll know about it).

Component(x => x.BillingAddress);
Component(x => x.MailingAddress);

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 the ColumnPrefix method that's chained off the bodyless Component call.

Component(x => x.BillingAddress)
  .ColumnPrefix("Billing_");
0

精彩评论

暂无评论...
验证码 换一张
取 消