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

Wil*_* Am 1 c# fluent-nhibernate

Noob问题.

我有这种情况,我有这些对象:

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

class User
{
   string UserID;
   Address BillingAddress;
   Address MailingAddress;
   ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

Jam*_*ory 7

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

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


内联组件

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

  Component(x => x.BillingAddress, addr =>
  {
    addr.Map(x => x.Street);
    addr.Map(x => x.City);
  });
Run Code Online (Sandbox Code Playgroud)

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


ComponentMap

内联定义适用于一次性组件,但是当您拥有同一组件的多个实例时,它很快就会变得很烦人.ComponentMap通过将组件提取到一个独立的,可重用的定义中来解决这个问题.你只需要像使用它一样使用它ClassMap.

public class AddressMap : ComponentMap<Address>
{
  public AddressMap()
  {
    Map(x => x.Street);
    Map(x => x.City);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

Component(x => x.BillingAddress);
Component(x => x.MailingAddress);
Run Code Online (Sandbox Code Playgroud)

使用ComponentMap,根据包含组件的属性,根据需要自动创建列前缀.如果你需要自定义这个ColumnPrefix方法,那就是无体Component呼叫的链接方式.

Component(x => x.BillingAddress)
  .ColumnPrefix("Billing_");
Run Code Online (Sandbox Code Playgroud)