流利的nhibernate - 在一个表中存储和检索三个类

时间:2010-05-20 04:40:35

标签: c# fluent-nhibernate

Noob问题。

我遇到这种情况:

class Address
{      
   string Street;
   string City;
   ...
}

class User
{
   string UserID;
   Address BillingAddress;
   Address MailingAddress;
   ...
}

使用(流畅的)nHibernate存储此数据的正确方法是什么?我可以使用一个单独的地址表并创建一个引用,但它们是1:1的关系,所以我真的不想招致连接的开销。理想情况下,我会将其存储为单个平面记录。

所以,我的问题是,以这样的方式存储类'User'的实例的正确方法是什么,它将其内容以及两个地址存储为单个记录?我的知识是如何以两种地址记录获得不同的列名(例如BillingAddress_Street和MailingAddress_Street)的方式存储这些信息,以及如何将记录读回用户实例。

1 个答案:

答案 0 :(得分:7)

这些结构称为component。它们是一个规范化的结构,是表示数据的完全可接受的机制。

在Fluent NHibernate中,有几种方法可以映射组件。首先是内联映射,然后是外部ComponentMap。我建议你在你的情况下使用后者,并且在任何情况下,你有一个组件多次出现(在同一个实体或你的域中)。


内联组件

要映射组件,最简单的方法是使用Component方法并使用body lambda指定组件的组成方式。

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

这是你的地址映射。您需要为这两个地址重复此操作。


ComponentMap

内联定义适用于一次性组件,但是当您拥有相同组件的多个实例时,它很快就会变得无聊。 ComponentMap通过将您的组件提取到一个独立的,可重用的定义中来解决这个问题。您只需使用与ClassMap完全相同的方式。

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

然后在ClassMap中,你只需要使用无体Component方法;这指示Fluent NHibernate搜索匹配属性类型的ComponentMap(如果找不到,你就会知道它。)

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

使用ComponentMap,根据包含组件的属性,根据需要自动创建列前缀。如果您需要对此进行自定义,那么ColumnPrefix方法会锁定无体Component电话。

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